summaryrefslogtreecommitdiffstats
path: root/dom/bindings/test
diff options
context:
space:
mode:
Diffstat (limited to 'dom/bindings/test')
-rw-r--r--dom/bindings/test/Makefile.in17
-rw-r--r--dom/bindings/test/TestBindingHeader.h1804
-rw-r--r--dom/bindings/test/TestCImplementedInterface.h37
-rw-r--r--dom/bindings/test/TestCallback.webidl10
-rw-r--r--dom/bindings/test/TestCodeGen.webidl1537
-rw-r--r--dom/bindings/test/TestDictionary.webidl9
-rw-r--r--dom/bindings/test/TestExampleGen.webidl914
-rw-r--r--dom/bindings/test/TestFunctions.cpp315
-rw-r--r--dom/bindings/test/TestFunctions.h138
-rw-r--r--dom/bindings/test/TestInterfaceAsyncIterableDouble.cpp98
-rw-r--r--dom/bindings/test/TestInterfaceAsyncIterableDouble.h64
-rw-r--r--dom/bindings/test/TestInterfaceAsyncIterableDoubleUnion.cpp107
-rw-r--r--dom/bindings/test/TestInterfaceAsyncIterableDoubleUnion.h64
-rw-r--r--dom/bindings/test/TestInterfaceAsyncIterableSingle.cpp130
-rw-r--r--dom/bindings/test/TestInterfaceAsyncIterableSingle.h81
-rw-r--r--dom/bindings/test/TestInterfaceAsyncIterableSingleWithArgs.cpp118
-rw-r--r--dom/bindings/test/TestInterfaceAsyncIterableSingleWithArgs.h60
-rw-r--r--dom/bindings/test/TestInterfaceIterableDouble.cpp71
-rw-r--r--dom/bindings/test/TestInterfaceIterableDouble.h53
-rw-r--r--dom/bindings/test/TestInterfaceIterableDoubleUnion.cpp76
-rw-r--r--dom/bindings/test/TestInterfaceIterableDoubleUnion.h52
-rw-r--r--dom/bindings/test/TestInterfaceIterableSingle.cpp72
-rw-r--r--dom/bindings/test/TestInterfaceIterableSingle.h51
-rw-r--r--dom/bindings/test/TestInterfaceJS.sys.mjs220
-rw-r--r--dom/bindings/test/TestInterfaceLength.cpp24
-rw-r--r--dom/bindings/test/TestInterfaceLength.h39
-rw-r--r--dom/bindings/test/TestInterfaceMaplike.cpp74
-rw-r--r--dom/bindings/test/TestInterfaceMaplike.h52
-rw-r--r--dom/bindings/test/TestInterfaceMaplikeJSObject.cpp85
-rw-r--r--dom/bindings/test/TestInterfaceMaplikeJSObject.h55
-rw-r--r--dom/bindings/test/TestInterfaceMaplikeObject.cpp81
-rw-r--r--dom/bindings/test/TestInterfaceMaplikeObject.h55
-rw-r--r--dom/bindings/test/TestInterfaceObservableArray.cpp225
-rw-r--r--dom/bindings/test/TestInterfaceObservableArray.h115
-rw-r--r--dom/bindings/test/TestInterfaceSetlike.cpp51
-rw-r--r--dom/bindings/test/TestInterfaceSetlike.h44
-rw-r--r--dom/bindings/test/TestInterfaceSetlikeNode.cpp53
-rw-r--r--dom/bindings/test/TestInterfaceSetlikeNode.h46
-rw-r--r--dom/bindings/test/TestJSImplGen.webidl887
-rw-r--r--dom/bindings/test/TestJSImplInheritanceGen.webidl39
-rw-r--r--dom/bindings/test/TestTrialInterface.cpp24
-rw-r--r--dom/bindings/test/TestTrialInterface.h39
-rw-r--r--dom/bindings/test/TestTypedef.webidl7
-rw-r--r--dom/bindings/test/WrapperCachedNonISupportsTestInterface.cpp28
-rw-r--r--dom/bindings/test/WrapperCachedNonISupportsTestInterface.h45
-rw-r--r--dom/bindings/test/chrome.toml28
-rw-r--r--dom/bindings/test/file_InstanceOf.html11
-rw-r--r--dom/bindings/test/file_barewordGetsWindow_frame1.html1
-rw-r--r--dom/bindings/test/file_barewordGetsWindow_frame2.html1
-rw-r--r--dom/bindings/test/file_bug1808352_frame.html4
-rw-r--r--dom/bindings/test/file_bug1808352b_frame.html3
-rw-r--r--dom/bindings/test/file_bug775543.html5
-rw-r--r--dom/bindings/test/file_document_location_set_via_xray.html5
-rw-r--r--dom/bindings/test/file_dom_xrays.html24
-rw-r--r--dom/bindings/test/file_proxies_via_xray.html8
-rw-r--r--dom/bindings/test/forOf_iframe.html13
-rw-r--r--dom/bindings/test/mochitest.toml207
-rw-r--r--dom/bindings/test/moz.build69
-rw-r--r--dom/bindings/test/mozITestInterfaceJS.idl21
-rw-r--r--dom/bindings/test/test_ByteString.html31
-rw-r--r--dom/bindings/test/test_InstanceOf.html53
-rw-r--r--dom/bindings/test/test_Object.prototype_props.html21
-rw-r--r--dom/bindings/test/test_async_iterable.html300
-rw-r--r--dom/bindings/test/test_async_stacks.html109
-rw-r--r--dom/bindings/test/test_attributes_on_types.html246
-rw-r--r--dom/bindings/test/test_barewordGetsWindow.html60
-rw-r--r--dom/bindings/test/test_bug1036214.html141
-rw-r--r--dom/bindings/test/test_bug1041646.html49
-rw-r--r--dom/bindings/test/test_bug1123516_maplikesetlike.html278
-rw-r--r--dom/bindings/test/test_bug1123516_maplikesetlikechrome.xhtml70
-rw-r--r--dom/bindings/test/test_bug1123875.html15
-rw-r--r--dom/bindings/test/test_bug1287912.html36
-rw-r--r--dom/bindings/test/test_bug1457051.html34
-rw-r--r--dom/bindings/test/test_bug1808352.html24
-rw-r--r--dom/bindings/test/test_bug1808352b.html25
-rw-r--r--dom/bindings/test/test_bug560072.html34
-rw-r--r--dom/bindings/test/test_bug742191.html36
-rw-r--r--dom/bindings/test/test_bug759621.html29
-rw-r--r--dom/bindings/test/test_bug773326.html13
-rw-r--r--dom/bindings/test/test_bug775543.html36
-rw-r--r--dom/bindings/test/test_bug788369.html30
-rw-r--r--dom/bindings/test/test_bug852846.html34
-rw-r--r--dom/bindings/test/test_bug862092.html36
-rw-r--r--dom/bindings/test/test_callback_across_document_open.html22
-rw-r--r--dom/bindings/test/test_callback_default_thisval.html36
-rw-r--r--dom/bindings/test/test_callback_exceptions.html19
-rw-r--r--dom/bindings/test/test_cloneAndImportNode.html48
-rw-r--r--dom/bindings/test/test_crossOriginWindowSymbolAccess.html29
-rw-r--r--dom/bindings/test/test_defineProperty.html157
-rw-r--r--dom/bindings/test/test_document_location_set_via_xray.html48
-rw-r--r--dom/bindings/test/test_document_location_via_xray_cached.html35
-rw-r--r--dom/bindings/test/test_domProxyArrayLengthGetter.html28
-rw-r--r--dom/bindings/test/test_dom_xrays.html386
-rw-r--r--dom/bindings/test/test_enums.html16
-rw-r--r--dom/bindings/test/test_exceptionSanitization.html56
-rw-r--r--dom/bindings/test/test_exceptionThrowing.html56
-rw-r--r--dom/bindings/test/test_exception_messages.html83
-rw-r--r--dom/bindings/test/test_exception_options_from_jsimplemented.html166
-rw-r--r--dom/bindings/test/test_exceptions_from_jsimplemented.html56
-rw-r--r--dom/bindings/test/test_forOf.html87
-rw-r--r--dom/bindings/test/test_integers.html50
-rw-r--r--dom/bindings/test/test_interfaceLength.html34
-rw-r--r--dom/bindings/test/test_interfaceLength_chrome.html34
-rw-r--r--dom/bindings/test/test_interfaceName.html28
-rw-r--r--dom/bindings/test/test_interfaceToString.html45
-rw-r--r--dom/bindings/test/test_iterable.html241
-rw-r--r--dom/bindings/test/test_jsimplemented_cross_realm_this.html44
-rw-r--r--dom/bindings/test/test_jsimplemented_eventhandler.html47
-rw-r--r--dom/bindings/test/test_jsimplemented_subclassing.html31
-rw-r--r--dom/bindings/test/test_large_arraybuffers.html97
-rw-r--r--dom/bindings/test/test_large_imageData.html68
-rw-r--r--dom/bindings/test/test_lenientThis.html28
-rw-r--r--dom/bindings/test/test_lookupGetter.html49
-rw-r--r--dom/bindings/test/test_namedNoIndexed.html36
-rw-r--r--dom/bindings/test/test_named_getter_enumerability.html41
-rw-r--r--dom/bindings/test/test_observablearray.html546
-rw-r--r--dom/bindings/test/test_observablearray_helper.html376
-rw-r--r--dom/bindings/test/test_observablearray_proxyhandler.html859
-rw-r--r--dom/bindings/test/test_oom_reporting.html42
-rw-r--r--dom/bindings/test/test_prefOnConstructor.html57
-rw-r--r--dom/bindings/test/test_primitive_this.html44
-rw-r--r--dom/bindings/test/test_promise_rejections_from_jsimplemented.html143
-rw-r--r--dom/bindings/test/test_proxies_via_xray.html98
-rw-r--r--dom/bindings/test/test_proxy_accessors.html78
-rw-r--r--dom/bindings/test/test_proxy_expandos.html86
-rw-r--r--dom/bindings/test/test_proxy_missing_prop.html49
-rw-r--r--dom/bindings/test/test_remoteProxyAsPrototype.html37
-rw-r--r--dom/bindings/test/test_resizable_arraybufferview.html97
-rw-r--r--dom/bindings/test/test_returnUnion.html59
-rw-r--r--dom/bindings/test/test_sequence_detection.html53
-rw-r--r--dom/bindings/test/test_sequence_wrapping.html62
-rw-r--r--dom/bindings/test/test_setWithNamedGetterNoNamedSetter.html40
-rw-r--r--dom/bindings/test/test_stringBindings.html109
-rw-r--r--dom/bindings/test/test_throwing_method_noDCE.html30
-rw-r--r--dom/bindings/test/test_toJSON.html59
-rw-r--r--dom/bindings/test/test_traceProtos.html37
-rw-r--r--dom/bindings/test/test_treat_non_object_as_null.html39
-rw-r--r--dom/bindings/test/test_unforgeablesonexpando.html19
-rw-r--r--dom/bindings/test/test_usvstring.html43
-rw-r--r--dom/bindings/test/test_worker_UnwrapArg.html58
140 files changed, 15627 insertions, 0 deletions
diff --git a/dom/bindings/test/Makefile.in b/dom/bindings/test/Makefile.in
new file mode 100644
index 0000000000..e338cc30d0
--- /dev/null
+++ b/dom/bindings/test/Makefile.in
@@ -0,0 +1,17 @@
+# 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/.
+
+ifdef COMPILE_ENVIRONMENT
+
+include ../webidlsrcs.mk
+
+# $(test_sources) comes from webidlsrcs.mk.
+# TODO Update this variable in backend.mk.
+CPPSRCS += $(addprefix ../,$(test_sources))
+
+# Include rules.mk before any of our targets so our first target is coming from
+# rules.mk and running make with no target in this dir does the right thing.
+include $(topsrcdir)/config/rules.mk
+
+endif
diff --git a/dom/bindings/test/TestBindingHeader.h b/dom/bindings/test/TestBindingHeader.h
new file mode 100644
index 0000000000..4a7ea91ee8
--- /dev/null
+++ b/dom/bindings/test/TestBindingHeader.h
@@ -0,0 +1,1804 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/.
+ */
+
+#ifndef TestBindingHeader_h
+#define TestBindingHeader_h
+
+#include "mozilla/dom/BindingUtils.h"
+#include "mozilla/dom/Record.h"
+#include "mozilla/dom/TypedArray.h"
+#include "mozilla/ErrorResult.h"
+#include "nsCOMPtr.h"
+#include "nsGenericHTMLElement.h"
+#include "nsWrapperCache.h"
+#include "js/Object.h" // JS::GetClass
+
+// Forward declare this before we include TestCodeGenBinding.h, because that
+// header relies on including this one for it, for ParentDict. Hopefully it
+// won't begin to rely on it in more fundamental ways.
+namespace mozilla {
+namespace dom {
+class DocGroup;
+class TestExternalInterface;
+class TestUnionArguments;
+class Promise;
+} // namespace dom
+} // namespace mozilla
+
+// We don't export TestCodeGenBinding.h, but it's right in our parent dir.
+#include "../TestCodeGenBinding.h"
+
+extern bool TestFuncControlledMember(JSContext*, JSObject*);
+
+namespace mozilla {
+namespace dom {
+
+// IID for nsRenamedInterface
+#define NS_RENAMED_INTERFACE_IID \
+ { \
+ 0xd4b19ef3, 0xe68b, 0x4e3f, { \
+ 0x94, 0xbc, 0xc9, 0xde, 0x3a, 0x69, 0xb0, 0xe8 \
+ } \
+ }
+
+class nsRenamedInterface : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_RENAMED_INTERFACE_IID)
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsRenamedInterface, NS_RENAMED_INTERFACE_IID)
+
+// IID for the TestExternalInterface
+#define NS_TEST_EXTERNAL_INTERFACE_IID \
+ { \
+ 0xd5ba0c99, 0x9b1d, 0x4e71, { \
+ 0x8a, 0x94, 0x56, 0x38, 0x6c, 0xa3, 0xda, 0x3d \
+ } \
+ }
+class TestExternalInterface : public nsISupports {
+ public:
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_TEST_EXTERNAL_INTERFACE_IID)
+ NS_DECL_ISUPPORTS
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(TestExternalInterface,
+ NS_TEST_EXTERNAL_INTERFACE_IID)
+
+class TestNonWrapperCacheInterface : public nsISupports {
+ public:
+ NS_DECL_ISUPPORTS
+
+ bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto,
+ JS::MutableHandle<JSObject*> aReflector);
+};
+
+class OnlyForUseInConstructor : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+ // We need a GetParentObject to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+};
+
+class TestInterface : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject and GetDocGroup to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+ DocGroup* GetDocGroup() const;
+
+ // And now our actual WebIDL API
+ // Constructors
+ static already_AddRefed<TestInterface> Constructor(const GlobalObject&);
+ static already_AddRefed<TestInterface> Constructor(const GlobalObject&,
+ const nsAString&);
+ static already_AddRefed<TestInterface> Constructor(const GlobalObject&,
+ uint32_t,
+ const Nullable<bool>&);
+ static already_AddRefed<TestInterface> Constructor(const GlobalObject&,
+ TestInterface*);
+ static already_AddRefed<TestInterface> Constructor(const GlobalObject&,
+ uint32_t, TestInterface&);
+
+ static already_AddRefed<TestInterface> Constructor(const GlobalObject&,
+ const ArrayBuffer&);
+ static already_AddRefed<TestInterface> Constructor(const GlobalObject&,
+ const Uint8Array&);
+ /* static
+ already_AddRefed<TestInterface>
+ Constructor(const GlobalObject&, uint32_t, uint32_t,
+ const TestInterfaceOrOnlyForUseInConstructor&);
+ */
+
+ static already_AddRefed<TestInterface> Test(const GlobalObject&,
+ ErrorResult&);
+ static already_AddRefed<TestInterface> Test(const GlobalObject&,
+ const nsAString&, ErrorResult&);
+ static already_AddRefed<TestInterface> Test(const GlobalObject&,
+ const nsACString&, ErrorResult&);
+
+ static already_AddRefed<TestInterface> Test2(
+ const GlobalObject&, const DictForConstructor&, JS::Handle<JS::Value>,
+ JS::Handle<JSObject*>, JS::Handle<JSObject*>, const Sequence<Dict>&,
+ JS::Handle<JS::Value>, const Optional<JS::Handle<JSObject*>>&,
+ const Optional<JS::Handle<JSObject*>>&, ErrorResult&);
+
+ static already_AddRefed<TestInterface> Test3(const GlobalObject&,
+ const LongOrStringAnyRecord&,
+ ErrorResult&);
+
+ static already_AddRefed<TestInterface> Test4(
+ const GlobalObject&, const Record<nsString, Record<nsString, JS::Value>>&,
+ ErrorResult&);
+
+ static already_AddRefed<TestInterface> Test5(
+ const GlobalObject&,
+ const Record<
+ nsString,
+ Sequence<Record<nsString,
+ Record<nsString, Sequence<Sequence<JS::Value>>>>>>&,
+ ErrorResult&);
+
+ static already_AddRefed<TestInterface> Test6(
+ const GlobalObject&,
+ const Sequence<Record<
+ nsCString,
+ Sequence<Sequence<Record<nsCString, Record<nsString, JS::Value>>>>>>&,
+ ErrorResult&);
+
+ // Integer types
+ int8_t ReadonlyByte();
+ int8_t WritableByte();
+ void SetWritableByte(int8_t);
+ void PassByte(int8_t);
+ int8_t ReceiveByte();
+ void PassOptionalByte(const Optional<int8_t>&);
+ void PassOptionalByteBeforeRequired(const Optional<int8_t>&, int8_t);
+ void PassOptionalByteWithDefault(int8_t);
+ void PassOptionalByteWithDefaultBeforeRequired(int8_t, int8_t);
+ void PassNullableByte(const Nullable<int8_t>&);
+ void PassOptionalNullableByte(const Optional<Nullable<int8_t>>&);
+ void PassVariadicByte(const Sequence<int8_t>&);
+ int8_t CachedByte();
+ int8_t CachedConstantByte();
+ int8_t CachedWritableByte();
+ void SetCachedWritableByte(int8_t);
+ int8_t SideEffectFreeByte();
+ void SetSideEffectFreeByte(int8_t);
+ int8_t DomDependentByte();
+ void SetDomDependentByte(int8_t);
+ int8_t ConstantByte();
+ int8_t DeviceStateDependentByte();
+ int8_t ReturnByteSideEffectFree();
+ int8_t ReturnDOMDependentByte();
+ int8_t ReturnConstantByte();
+ int8_t ReturnDeviceStateDependentByte();
+
+ void UnsafePrerenderMethod();
+ int32_t UnsafePrerenderWritable();
+ void SetUnsafePrerenderWritable(int32_t);
+ int32_t UnsafePrerenderReadonly();
+ int16_t ReadonlyShort();
+ int16_t WritableShort();
+ void SetWritableShort(int16_t);
+ void PassShort(int16_t);
+ int16_t ReceiveShort();
+ void PassOptionalShort(const Optional<int16_t>&);
+ void PassOptionalShortWithDefault(int16_t);
+
+ int32_t ReadonlyLong();
+ int32_t WritableLong();
+ void SetWritableLong(int32_t);
+ void PassLong(int32_t);
+ int16_t ReceiveLong();
+ void PassOptionalLong(const Optional<int32_t>&);
+ void PassOptionalLongWithDefault(int32_t);
+
+ int64_t ReadonlyLongLong();
+ int64_t WritableLongLong();
+ void SetWritableLongLong(int64_t);
+ void PassLongLong(int64_t);
+ int64_t ReceiveLongLong();
+ void PassOptionalLongLong(const Optional<int64_t>&);
+ void PassOptionalLongLongWithDefault(int64_t);
+
+ uint8_t ReadonlyOctet();
+ uint8_t WritableOctet();
+ void SetWritableOctet(uint8_t);
+ void PassOctet(uint8_t);
+ uint8_t ReceiveOctet();
+ void PassOptionalOctet(const Optional<uint8_t>&);
+ void PassOptionalOctetWithDefault(uint8_t);
+
+ uint16_t ReadonlyUnsignedShort();
+ uint16_t WritableUnsignedShort();
+ void SetWritableUnsignedShort(uint16_t);
+ void PassUnsignedShort(uint16_t);
+ uint16_t ReceiveUnsignedShort();
+ void PassOptionalUnsignedShort(const Optional<uint16_t>&);
+ void PassOptionalUnsignedShortWithDefault(uint16_t);
+
+ uint32_t ReadonlyUnsignedLong();
+ uint32_t WritableUnsignedLong();
+ void SetWritableUnsignedLong(uint32_t);
+ void PassUnsignedLong(uint32_t);
+ uint32_t ReceiveUnsignedLong();
+ void PassOptionalUnsignedLong(const Optional<uint32_t>&);
+ void PassOptionalUnsignedLongWithDefault(uint32_t);
+
+ uint64_t ReadonlyUnsignedLongLong();
+ uint64_t WritableUnsignedLongLong();
+ void SetWritableUnsignedLongLong(uint64_t);
+ void PassUnsignedLongLong(uint64_t);
+ uint64_t ReceiveUnsignedLongLong();
+ void PassOptionalUnsignedLongLong(const Optional<uint64_t>&);
+ void PassOptionalUnsignedLongLongWithDefault(uint64_t);
+
+ float WritableFloat() const;
+ void SetWritableFloat(float);
+ float WritableUnrestrictedFloat() const;
+ void SetWritableUnrestrictedFloat(float);
+ Nullable<float> GetWritableNullableFloat() const;
+ void SetWritableNullableFloat(const Nullable<float>&);
+ Nullable<float> GetWritableNullableUnrestrictedFloat() const;
+ void SetWritableNullableUnrestrictedFloat(const Nullable<float>&);
+ double WritableDouble() const;
+ void SetWritableDouble(double);
+ double WritableUnrestrictedDouble() const;
+ void SetWritableUnrestrictedDouble(double);
+ Nullable<double> GetWritableNullableDouble() const;
+ void SetWritableNullableDouble(const Nullable<double>&);
+ Nullable<double> GetWritableNullableUnrestrictedDouble() const;
+ void SetWritableNullableUnrestrictedDouble(const Nullable<double>&);
+ void PassFloat(float, float, const Nullable<float>&, const Nullable<float>&,
+ double, double, const Nullable<double>&,
+ const Nullable<double>&, const Sequence<float>&,
+ const Sequence<float>&, const Sequence<Nullable<float>>&,
+ const Sequence<Nullable<float>>&, const Sequence<double>&,
+ const Sequence<double>&, const Sequence<Nullable<double>>&,
+ const Sequence<Nullable<double>>&);
+ void PassLenientFloat(float, float, const Nullable<float>&,
+ const Nullable<float>&, double, double,
+ const Nullable<double>&, const Nullable<double>&,
+ const Sequence<float>&, const Sequence<float>&,
+ const Sequence<Nullable<float>>&,
+ const Sequence<Nullable<float>>&,
+ const Sequence<double>&, const Sequence<double>&,
+ const Sequence<Nullable<double>>&,
+ const Sequence<Nullable<double>>&);
+ float LenientFloatAttr() const;
+ void SetLenientFloatAttr(float);
+ double LenientDoubleAttr() const;
+ void SetLenientDoubleAttr(double);
+
+ void PassUnrestricted(float arg1, float arg2, float arg3, float arg4,
+ double arg5, double arg6, double arg7, double arg8);
+
+ // Interface types
+ already_AddRefed<TestInterface> ReceiveSelf();
+ already_AddRefed<TestInterface> ReceiveNullableSelf();
+ TestInterface* ReceiveWeakSelf();
+ TestInterface* ReceiveWeakNullableSelf();
+ void PassSelf(TestInterface&);
+ void PassNullableSelf(TestInterface*);
+ already_AddRefed<TestInterface> NonNullSelf();
+ void SetNonNullSelf(TestInterface&);
+ already_AddRefed<TestInterface> GetNullableSelf();
+ already_AddRefed<TestInterface> CachedSelf();
+ void SetNullableSelf(TestInterface*);
+ void PassOptionalSelf(const Optional<TestInterface*>&);
+ void PassOptionalNonNullSelf(const Optional<NonNull<TestInterface>>&);
+ void PassOptionalSelfWithDefault(TestInterface*);
+
+ already_AddRefed<TestNonWrapperCacheInterface>
+ ReceiveNonWrapperCacheInterface();
+ already_AddRefed<TestNonWrapperCacheInterface>
+ ReceiveNullableNonWrapperCacheInterface();
+ void ReceiveNonWrapperCacheInterfaceSequence(
+ nsTArray<RefPtr<TestNonWrapperCacheInterface>>&);
+ void ReceiveNullableNonWrapperCacheInterfaceSequence(
+ nsTArray<RefPtr<TestNonWrapperCacheInterface>>&);
+ void ReceiveNonWrapperCacheInterfaceNullableSequence(
+ Nullable<nsTArray<RefPtr<TestNonWrapperCacheInterface>>>&);
+ void ReceiveNullableNonWrapperCacheInterfaceNullableSequence(
+ Nullable<nsTArray<RefPtr<TestNonWrapperCacheInterface>>>&);
+
+ already_AddRefed<TestExternalInterface> ReceiveExternal();
+ already_AddRefed<TestExternalInterface> ReceiveNullableExternal();
+ TestExternalInterface* ReceiveWeakExternal();
+ TestExternalInterface* ReceiveWeakNullableExternal();
+ void PassExternal(TestExternalInterface*);
+ void PassNullableExternal(TestExternalInterface*);
+ already_AddRefed<TestExternalInterface> NonNullExternal();
+ void SetNonNullExternal(TestExternalInterface*);
+ already_AddRefed<TestExternalInterface> GetNullableExternal();
+ void SetNullableExternal(TestExternalInterface*);
+ void PassOptionalExternal(const Optional<TestExternalInterface*>&);
+ void PassOptionalNonNullExternal(const Optional<TestExternalInterface*>&);
+ void PassOptionalExternalWithDefault(TestExternalInterface*);
+
+ already_AddRefed<TestCallbackInterface> ReceiveCallbackInterface();
+ already_AddRefed<TestCallbackInterface> ReceiveNullableCallbackInterface();
+ TestCallbackInterface* ReceiveWeakCallbackInterface();
+ TestCallbackInterface* ReceiveWeakNullableCallbackInterface();
+ void PassCallbackInterface(TestCallbackInterface&);
+ void PassNullableCallbackInterface(TestCallbackInterface*);
+ already_AddRefed<TestCallbackInterface> NonNullCallbackInterface();
+ void SetNonNullCallbackInterface(TestCallbackInterface&);
+ already_AddRefed<TestCallbackInterface> GetNullableCallbackInterface();
+ void SetNullableCallbackInterface(TestCallbackInterface*);
+ void PassOptionalCallbackInterface(
+ const Optional<RefPtr<TestCallbackInterface>>&);
+ void PassOptionalNonNullCallbackInterface(
+ const Optional<OwningNonNull<TestCallbackInterface>>&);
+ void PassOptionalCallbackInterfaceWithDefault(TestCallbackInterface*);
+
+ // Sequence types
+ void GetReadonlySequence(nsTArray<int32_t>&);
+ void GetReadonlySequenceOfDictionaries(JSContext*, nsTArray<Dict>&);
+ void GetReadonlyNullableSequenceOfDictionaries(JSContext*,
+ Nullable<nsTArray<Dict>>&);
+ void GetReadonlyFrozenSequence(JSContext*, nsTArray<Dict>&);
+ void GetReadonlyFrozenNullableSequence(JSContext*, Nullable<nsTArray<Dict>>&);
+ void ReceiveSequence(nsTArray<int32_t>&);
+ void ReceiveNullableSequence(Nullable<nsTArray<int32_t>>&);
+ void ReceiveSequenceOfNullableInts(nsTArray<Nullable<int32_t>>&);
+ void ReceiveNullableSequenceOfNullableInts(
+ Nullable<nsTArray<Nullable<int32_t>>>&);
+ void PassSequence(const Sequence<int32_t>&);
+ void PassNullableSequence(const Nullable<Sequence<int32_t>>&);
+ void PassSequenceOfNullableInts(const Sequence<Nullable<int32_t>>&);
+ void PassOptionalSequenceOfNullableInts(
+ const Optional<Sequence<Nullable<int32_t>>>&);
+ void PassOptionalNullableSequenceOfNullableInts(
+ const Optional<Nullable<Sequence<Nullable<int32_t>>>>&);
+ void ReceiveCastableObjectSequence(nsTArray<RefPtr<TestInterface>>&);
+ void ReceiveCallbackObjectSequence(nsTArray<RefPtr<TestCallbackInterface>>&);
+ void ReceiveNullableCastableObjectSequence(nsTArray<RefPtr<TestInterface>>&);
+ void ReceiveNullableCallbackObjectSequence(
+ nsTArray<RefPtr<TestCallbackInterface>>&);
+ void ReceiveCastableObjectNullableSequence(
+ Nullable<nsTArray<RefPtr<TestInterface>>>&);
+ void ReceiveNullableCastableObjectNullableSequence(
+ Nullable<nsTArray<RefPtr<TestInterface>>>&);
+ void ReceiveWeakCastableObjectSequence(nsTArray<RefPtr<TestInterface>>&);
+ void ReceiveWeakNullableCastableObjectSequence(
+ nsTArray<RefPtr<TestInterface>>&);
+ void ReceiveWeakCastableObjectNullableSequence(
+ Nullable<nsTArray<RefPtr<TestInterface>>>&);
+ void ReceiveWeakNullableCastableObjectNullableSequence(
+ Nullable<nsTArray<RefPtr<TestInterface>>>&);
+ void PassCastableObjectSequence(
+ const Sequence<OwningNonNull<TestInterface>>&);
+ void PassNullableCastableObjectSequence(
+ const Sequence<RefPtr<TestInterface>>&);
+ void PassCastableObjectNullableSequence(
+ const Nullable<Sequence<OwningNonNull<TestInterface>>>&);
+ void PassNullableCastableObjectNullableSequence(
+ const Nullable<Sequence<RefPtr<TestInterface>>>&);
+ void PassOptionalSequence(const Optional<Sequence<int32_t>>&);
+ void PassOptionalSequenceWithDefaultValue(const Sequence<int32_t>&);
+ void PassOptionalNullableSequence(
+ const Optional<Nullable<Sequence<int32_t>>>&);
+ void PassOptionalNullableSequenceWithDefaultValue(
+ const Nullable<Sequence<int32_t>>&);
+ void PassOptionalNullableSequenceWithDefaultValue2(
+ const Nullable<Sequence<int32_t>>&);
+ void PassOptionalObjectSequence(
+ const Optional<Sequence<OwningNonNull<TestInterface>>>&);
+ void PassExternalInterfaceSequence(
+ const Sequence<RefPtr<TestExternalInterface>>&);
+ void PassNullableExternalInterfaceSequence(
+ const Sequence<RefPtr<TestExternalInterface>>&);
+
+ void ReceiveStringSequence(nsTArray<nsString>&);
+ void PassStringSequence(const Sequence<nsString>&);
+
+ void ReceiveByteStringSequence(nsTArray<nsCString>&);
+ void PassByteStringSequence(const Sequence<nsCString>&);
+
+ void ReceiveUTF8StringSequence(nsTArray<nsCString>&);
+ void PassUTF8StringSequence(const Sequence<nsCString>&);
+
+ void ReceiveAnySequence(JSContext*, nsTArray<JS::Value>&);
+ void ReceiveNullableAnySequence(JSContext*, Nullable<nsTArray<JS::Value>>&);
+ void ReceiveAnySequenceSequence(JSContext*, nsTArray<nsTArray<JS::Value>>&);
+
+ void ReceiveObjectSequence(JSContext*, nsTArray<JSObject*>&);
+ void ReceiveNullableObjectSequence(JSContext*, nsTArray<JSObject*>&);
+
+ void PassSequenceOfSequences(const Sequence<Sequence<int32_t>>&);
+ void PassSequenceOfSequencesOfSequences(
+ const Sequence<Sequence<Sequence<int32_t>>>&);
+ void ReceiveSequenceOfSequences(nsTArray<nsTArray<int32_t>>&);
+ void ReceiveSequenceOfSequencesOfSequences(
+ nsTArray<nsTArray<nsTArray<int32_t>>>&);
+
+ // Record types
+ void PassRecord(const Record<nsString, int32_t>&);
+ void PassNullableRecord(const Nullable<Record<nsString, int32_t>>&);
+ void PassRecordOfNullableInts(const Record<nsString, Nullable<int32_t>>&);
+ void PassOptionalRecordOfNullableInts(
+ const Optional<Record<nsString, Nullable<int32_t>>>&);
+ void PassOptionalNullableRecordOfNullableInts(
+ const Optional<Nullable<Record<nsString, Nullable<int32_t>>>>&);
+ void PassCastableObjectRecord(
+ const Record<nsString, OwningNonNull<TestInterface>>&);
+ void PassNullableCastableObjectRecord(
+ const Record<nsString, RefPtr<TestInterface>>&);
+ void PassCastableObjectNullableRecord(
+ const Nullable<Record<nsString, OwningNonNull<TestInterface>>>&);
+ void PassNullableCastableObjectNullableRecord(
+ const Nullable<Record<nsString, RefPtr<TestInterface>>>&);
+ void PassOptionalRecord(const Optional<Record<nsString, int32_t>>&);
+ void PassOptionalNullableRecord(
+ const Optional<Nullable<Record<nsString, int32_t>>>&);
+ void PassOptionalNullableRecordWithDefaultValue(
+ const Nullable<Record<nsString, int32_t>>&);
+ void PassOptionalObjectRecord(
+ const Optional<Record<nsString, OwningNonNull<TestInterface>>>&);
+ void PassExternalInterfaceRecord(
+ const Record<nsString, RefPtr<TestExternalInterface>>&);
+ void PassNullableExternalInterfaceRecord(
+ const Record<nsString, RefPtr<TestExternalInterface>>&);
+ void PassStringRecord(const Record<nsString, nsString>&);
+ void PassByteStringRecord(const Record<nsString, nsCString>&);
+ void PassUTF8StringRecord(const Record<nsString, nsCString>&);
+ void PassRecordOfRecords(const Record<nsString, Record<nsString, int32_t>>&);
+ void ReceiveRecord(Record<nsString, int32_t>&);
+ void ReceiveNullableRecord(Nullable<Record<nsString, int32_t>>&);
+ void ReceiveRecordOfNullableInts(Record<nsString, Nullable<int32_t>>&);
+ void ReceiveNullableRecordOfNullableInts(
+ Nullable<Record<nsString, Nullable<int32_t>>>&);
+ void ReceiveRecordOfRecords(Record<nsString, Record<nsString, int32_t>>&);
+ void ReceiveAnyRecord(JSContext*, Record<nsString, JS::Value>&);
+
+ // Typed array types
+ void PassArrayBuffer(const ArrayBuffer&);
+ void PassNullableArrayBuffer(const Nullable<ArrayBuffer>&);
+ void PassOptionalArrayBuffer(const Optional<ArrayBuffer>&);
+ void PassOptionalNullableArrayBuffer(const Optional<Nullable<ArrayBuffer>>&);
+ void PassOptionalNullableArrayBufferWithDefaultValue(
+ const Nullable<ArrayBuffer>&);
+ void PassArrayBufferView(const ArrayBufferView&);
+ void PassInt8Array(const Int8Array&);
+ void PassInt16Array(const Int16Array&);
+ void PassInt32Array(const Int32Array&);
+ void PassUint8Array(const Uint8Array&);
+ void PassUint16Array(const Uint16Array&);
+ void PassUint32Array(const Uint32Array&);
+ void PassUint8ClampedArray(const Uint8ClampedArray&);
+ void PassFloat32Array(const Float32Array&);
+ void PassFloat64Array(const Float64Array&);
+ void PassSequenceOfArrayBuffers(const Sequence<ArrayBuffer>&);
+ void PassSequenceOfNullableArrayBuffers(
+ const Sequence<Nullable<ArrayBuffer>>&);
+ void PassRecordOfArrayBuffers(const Record<nsString, ArrayBuffer>&);
+ void PassRecordOfNullableArrayBuffers(
+ const Record<nsString, Nullable<ArrayBuffer>>&);
+ void PassVariadicTypedArray(const Sequence<Float32Array>&);
+ void PassVariadicNullableTypedArray(const Sequence<Nullable<Float32Array>>&);
+ void ReceiveUint8Array(JSContext*, JS::MutableHandle<JSObject*>);
+ void SetUint8ArrayAttr(const Uint8Array&);
+ void GetUint8ArrayAttr(JSContext*, JS::MutableHandle<JSObject*>);
+
+ // DOMString types
+ void PassString(const nsAString&);
+ void PassNullableString(const nsAString&);
+ void PassOptionalString(const Optional<nsAString>&);
+ void PassOptionalStringWithDefaultValue(const nsAString&);
+ void PassOptionalNullableString(const Optional<nsAString>&);
+ void PassOptionalNullableStringWithDefaultValue(const nsAString&);
+ void PassVariadicString(const Sequence<nsString>&);
+ void ReceiveString(DOMString&);
+
+ // ByteString types
+ void PassByteString(const nsCString&);
+ void PassNullableByteString(const nsCString&);
+ void PassOptionalByteString(const Optional<nsCString>&);
+ void PassOptionalByteStringWithDefaultValue(const nsCString&);
+ void PassOptionalNullableByteString(const Optional<nsCString>&);
+ void PassOptionalNullableByteStringWithDefaultValue(const nsCString&);
+ void PassVariadicByteString(const Sequence<nsCString>&);
+ void PassOptionalUnionByteString(const Optional<ByteStringOrLong>&);
+ void PassOptionalUnionByteStringWithDefaultValue(const ByteStringOrLong&);
+
+ // UTF8String types
+ void PassUTF8String(const nsACString&);
+ void PassNullableUTF8String(const nsACString&);
+ void PassOptionalUTF8String(const Optional<nsACString>&);
+ void PassOptionalUTF8StringWithDefaultValue(const nsACString&);
+ void PassOptionalNullableUTF8String(const Optional<nsACString>&);
+ void PassOptionalNullableUTF8StringWithDefaultValue(const nsACString&);
+ void PassVariadicUTF8String(const Sequence<nsCString>&);
+ void PassOptionalUnionUTF8String(const Optional<UTF8StringOrLong>&);
+ void PassOptionalUnionUTF8StringWithDefaultValue(const UTF8StringOrLong&);
+
+ // USVString types
+ void PassUSVS(const nsAString&);
+ void PassNullableUSVS(const nsAString&);
+ void PassOptionalUSVS(const Optional<nsAString>&);
+ void PassOptionalUSVSWithDefaultValue(const nsAString&);
+ void PassOptionalNullableUSVS(const Optional<nsAString>&);
+ void PassOptionalNullableUSVSWithDefaultValue(const nsAString&);
+ void PassVariadicUSVS(const Sequence<nsString>&);
+ void ReceiveUSVS(DOMString&);
+
+ // JSString types
+ void PassJSString(JSContext*, JS::Handle<JSString*>);
+ void PassOptionalJSStringWithDefaultValue(JSContext*, JS::Handle<JSString*>);
+ void ReceiveJSString(JSContext*, JS::MutableHandle<JSString*>);
+ void GetReadonlyJSStringAttr(JSContext*, JS::MutableHandle<JSString*>);
+ void GetJsStringAttr(JSContext*, JS::MutableHandle<JSString*>);
+ void SetJsStringAttr(JSContext*, JS::Handle<JSString*>);
+
+ // Enumerated types
+ void PassEnum(TestEnum);
+ void PassNullableEnum(const Nullable<TestEnum>&);
+ void PassOptionalEnum(const Optional<TestEnum>&);
+ void PassEnumWithDefault(TestEnum);
+ void PassOptionalNullableEnum(const Optional<Nullable<TestEnum>>&);
+ void PassOptionalNullableEnumWithDefaultValue(const Nullable<TestEnum>&);
+ void PassOptionalNullableEnumWithDefaultValue2(const Nullable<TestEnum>&);
+ TestEnum ReceiveEnum();
+ Nullable<TestEnum> ReceiveNullableEnum();
+ TestEnum EnumAttribute();
+ TestEnum ReadonlyEnumAttribute();
+ void SetEnumAttribute(TestEnum);
+
+ // Callback types
+ void PassCallback(TestCallback&);
+ void PassNullableCallback(TestCallback*);
+ void PassOptionalCallback(const Optional<OwningNonNull<TestCallback>>&);
+ void PassOptionalNullableCallback(const Optional<RefPtr<TestCallback>>&);
+ void PassOptionalNullableCallbackWithDefaultValue(TestCallback*);
+ already_AddRefed<TestCallback> ReceiveCallback();
+ already_AddRefed<TestCallback> ReceiveNullableCallback();
+ void PassNullableTreatAsNullCallback(TestTreatAsNullCallback*);
+ void PassOptionalNullableTreatAsNullCallback(
+ const Optional<RefPtr<TestTreatAsNullCallback>>&);
+ void PassOptionalNullableTreatAsNullCallbackWithDefaultValue(
+ TestTreatAsNullCallback*);
+ void SetTreatAsNullCallback(TestTreatAsNullCallback&);
+ already_AddRefed<TestTreatAsNullCallback> TreatAsNullCallback();
+ void SetNullableTreatAsNullCallback(TestTreatAsNullCallback*);
+ already_AddRefed<TestTreatAsNullCallback> GetNullableTreatAsNullCallback();
+
+ void ForceCallbackGeneration(
+ TestIntegerReturn&, TestNullableIntegerReturn&, TestBooleanReturn&,
+ TestFloatReturn&, TestStringReturn&, TestEnumReturn&,
+ TestInterfaceReturn&, TestNullableInterfaceReturn&,
+ TestExternalInterfaceReturn&, TestNullableExternalInterfaceReturn&,
+ TestCallbackInterfaceReturn&, TestNullableCallbackInterfaceReturn&,
+ TestCallbackReturn&, TestNullableCallbackReturn&, TestObjectReturn&,
+ TestNullableObjectReturn&, TestTypedArrayReturn&,
+ TestNullableTypedArrayReturn&, TestSequenceReturn&,
+ TestNullableSequenceReturn&, TestIntegerArguments&,
+ TestInterfaceArguments&, TestStringEnumArguments&, TestObjectArguments&,
+ TestOptionalArguments&, TestUnionArguments&, TestUndefinedConstruction&,
+ TestIntegerConstruction&, TestBooleanConstruction&,
+ TestFloatConstruction&, TestStringConstruction&, TestEnumConstruction&,
+ TestInterfaceConstruction&, TestExternalInterfaceConstruction&,
+ TestCallbackInterfaceConstruction&, TestCallbackConstruction&,
+ TestObjectConstruction&, TestTypedArrayConstruction&,
+ TestSequenceConstruction&);
+
+ // Any types
+ void PassAny(JSContext*, JS::Handle<JS::Value>);
+ void PassVariadicAny(JSContext*, const Sequence<JS::Value>&);
+ void PassOptionalAny(JSContext*, JS::Handle<JS::Value>);
+ void PassAnyDefaultNull(JSContext*, JS::Handle<JS::Value>);
+ void PassSequenceOfAny(JSContext*, const Sequence<JS::Value>&);
+ void PassNullableSequenceOfAny(JSContext*,
+ const Nullable<Sequence<JS::Value>>&);
+ void PassOptionalSequenceOfAny(JSContext*,
+ const Optional<Sequence<JS::Value>>&);
+ void PassOptionalNullableSequenceOfAny(
+ JSContext*, const Optional<Nullable<Sequence<JS::Value>>>&);
+ void PassOptionalSequenceOfAnyWithDefaultValue(
+ JSContext*, const Nullable<Sequence<JS::Value>>&);
+ void PassSequenceOfSequenceOfAny(JSContext*,
+ const Sequence<Sequence<JS::Value>>&);
+ void PassSequenceOfNullableSequenceOfAny(
+ JSContext*, const Sequence<Nullable<Sequence<JS::Value>>>&);
+ void PassNullableSequenceOfNullableSequenceOfAny(
+ JSContext*, const Nullable<Sequence<Nullable<Sequence<JS::Value>>>>&);
+ void PassOptionalNullableSequenceOfNullableSequenceOfAny(
+ JSContext*,
+ const Optional<Nullable<Sequence<Nullable<Sequence<JS::Value>>>>>&);
+ void PassRecordOfAny(JSContext*, const Record<nsString, JS::Value>&);
+ void PassNullableRecordOfAny(JSContext*,
+ const Nullable<Record<nsString, JS::Value>>&);
+ void PassOptionalRecordOfAny(JSContext*,
+ const Optional<Record<nsString, JS::Value>>&);
+ void PassOptionalNullableRecordOfAny(
+ JSContext*, const Optional<Nullable<Record<nsString, JS::Value>>>&);
+ void PassOptionalRecordOfAnyWithDefaultValue(
+ JSContext*, const Nullable<Record<nsString, JS::Value>>&);
+ void PassRecordOfRecordOfAny(
+ JSContext*, const Record<nsString, Record<nsString, JS::Value>>&);
+ void PassRecordOfNullableRecordOfAny(
+ JSContext*,
+ const Record<nsString, Nullable<Record<nsString, JS::Value>>>&);
+ void PassNullableRecordOfNullableRecordOfAny(
+ JSContext*,
+ const Nullable<Record<nsString, Nullable<Record<nsString, JS::Value>>>>&);
+ void PassOptionalNullableRecordOfNullableRecordOfAny(
+ JSContext*,
+ const Optional<
+ Nullable<Record<nsString, Nullable<Record<nsString, JS::Value>>>>>&);
+ void PassOptionalNullableRecordOfNullableSequenceOfAny(
+ JSContext*,
+ const Optional<
+ Nullable<Record<nsString, Nullable<Sequence<JS::Value>>>>>&);
+ void PassOptionalNullableSequenceOfNullableRecordOfAny(
+ JSContext*,
+ const Optional<
+ Nullable<Sequence<Nullable<Record<nsString, JS::Value>>>>>&);
+ void ReceiveAny(JSContext*, JS::MutableHandle<JS::Value>);
+
+ // object types
+ void PassObject(JSContext*, JS::Handle<JSObject*>);
+ void PassVariadicObject(JSContext*, const Sequence<JSObject*>&);
+ void PassNullableObject(JSContext*, JS::Handle<JSObject*>);
+ void PassVariadicNullableObject(JSContext*, const Sequence<JSObject*>&);
+ void PassOptionalObject(JSContext*, const Optional<JS::Handle<JSObject*>>&);
+ void PassOptionalNullableObject(JSContext*,
+ const Optional<JS::Handle<JSObject*>>&);
+ void PassOptionalNullableObjectWithDefaultValue(JSContext*,
+ JS::Handle<JSObject*>);
+ void PassSequenceOfObject(JSContext*, const Sequence<JSObject*>&);
+ void PassSequenceOfNullableObject(JSContext*, const Sequence<JSObject*>&);
+ void PassNullableSequenceOfObject(JSContext*,
+ const Nullable<Sequence<JSObject*>>&);
+ void PassOptionalNullableSequenceOfNullableSequenceOfObject(
+ JSContext*,
+ const Optional<Nullable<Sequence<Nullable<Sequence<JSObject*>>>>>&);
+ void PassOptionalNullableSequenceOfNullableSequenceOfNullableObject(
+ JSContext*,
+ const Optional<Nullable<Sequence<Nullable<Sequence<JSObject*>>>>>&);
+ void PassRecordOfObject(JSContext*, const Record<nsString, JSObject*>&);
+ void ReceiveObject(JSContext*, JS::MutableHandle<JSObject*>);
+ void ReceiveNullableObject(JSContext*, JS::MutableHandle<JSObject*>);
+
+ // Union types
+ void PassUnion(JSContext*, const ObjectOrLong& arg);
+ void PassUnionWithNullable(JSContext* cx, const ObjectOrNullOrLong& arg) {
+ OwningObjectOrLong returnValue;
+ if (arg.IsNull()) {
+ } else if (arg.IsObject()) {
+ JS::Rooted<JSObject*> obj(cx, arg.GetAsObject());
+ JS::GetClass(obj);
+ returnValue.SetAsObject() = obj;
+ } else {
+ int32_t i = arg.GetAsLong();
+ i += 1;
+ returnValue.SetAsLong() = i;
+ }
+ }
+#ifdef DEBUG
+ void PassUnion2(const LongOrBoolean& arg);
+ void PassUnion3(JSContext*, const ObjectOrLongOrBoolean& arg);
+ void PassUnion4(const NodeOrLongOrBoolean& arg);
+ void PassUnion5(JSContext*, const ObjectOrBoolean& arg);
+ void PassUnion6(JSContext*, const ObjectOrString& arg);
+ void PassUnion7(JSContext*, const ObjectOrStringOrLong& arg);
+ void PassUnion8(JSContext*, const ObjectOrStringOrBoolean& arg);
+ void PassUnion9(JSContext*, const ObjectOrStringOrLongOrBoolean& arg);
+ void PassUnion10(const EventInitOrLong& arg);
+ void PassUnion11(JSContext*, const CustomEventInitOrLong& arg);
+ void PassUnion12(const EventInitOrLong& arg);
+ void PassUnion13(JSContext*, const ObjectOrLongOrNull& arg);
+ void PassUnion14(JSContext*, const ObjectOrLongOrNull& arg);
+ void PassUnion15(const LongSequenceOrLong&);
+ void PassUnion16(const Optional<LongSequenceOrLong>&);
+ void PassUnion17(const LongSequenceOrNullOrLong&);
+ void PassUnion18(JSContext*, const ObjectSequenceOrLong&);
+ void PassUnion19(JSContext*, const Optional<ObjectSequenceOrLong>&);
+ void PassUnion20(JSContext*, const ObjectSequenceOrLong&);
+ void PassUnion21(const StringLongRecordOrLong&);
+ void PassUnion22(JSContext*, const StringObjectRecordOrLong&);
+ void PassUnion23(const ImageDataSequenceOrLong&);
+ void PassUnion24(const ImageDataOrNullSequenceOrLong&);
+ void PassUnion25(const ImageDataSequenceSequenceOrLong&);
+ void PassUnion26(const ImageDataOrNullSequenceSequenceOrLong&);
+ void PassUnion27(const StringSequenceOrEventInit&);
+ void PassUnion28(const EventInitOrStringSequence&);
+ void PassUnionWithCallback(const EventHandlerNonNullOrNullOrLong& arg);
+ void PassUnionWithByteString(const ByteStringOrLong&);
+ void PassUnionWithUTF8String(const UTF8StringOrLong&);
+ void PassUnionWithRecord(const StringStringRecordOrString&);
+ void PassUnionWithRecordAndSequence(
+ const StringStringRecordOrStringSequence&);
+ void PassUnionWithSequenceAndRecord(
+ const StringSequenceOrStringStringRecord&);
+ void PassUnionWithUSVS(const USVStringOrLong&);
+#endif
+ void PassNullableUnion(JSContext*, const Nullable<ObjectOrLong>&);
+ void PassOptionalUnion(JSContext*, const Optional<ObjectOrLong>&);
+ void PassOptionalNullableUnion(JSContext*,
+ const Optional<Nullable<ObjectOrLong>>&);
+ void PassOptionalNullableUnionWithDefaultValue(JSContext*,
+ const Nullable<ObjectOrLong>&);
+ // void PassUnionWithInterfaces(const TestInterfaceOrTestExternalInterface&
+ // arg); void PassUnionWithInterfacesAndNullable(const
+ // TestInterfaceOrNullOrTestExternalInterface& arg);
+ void PassUnionWithArrayBuffer(const UTF8StringOrArrayBuffer& aArg) {
+ auto processor = [](const Span<uint8_t>& aData) -> int { return -1; };
+ static_assert(
+ std::is_same_v<decltype(ProcessTypedArraysFixed(aArg, processor)),
+ Maybe<int>>,
+ "If the union can contain non-typedarray members we need to signal "
+ "that with a Maybe<…> rv.");
+ }
+ void PassUnionWithArrayBufferOrNull(
+ const UTF8StringOrArrayBufferOrNull& aArg) {
+ auto processor = [](const Span<uint8_t>& aData) -> int { return -1; };
+ static_assert(
+ std::is_same_v<decltype(ProcessTypedArraysFixed(aArg, processor)),
+ Maybe<int>>,
+ "If the union can contain non-typedarray members or null we need to "
+ "signal that with a Maybe<…> rv.");
+ }
+ void PassUnionWithTypedArrays(const ArrayBufferViewOrArrayBuffer& aArg) {
+ auto processor = [](const Span<uint8_t>& aData) -> int { return -1; };
+ static_assert(
+ std::is_same_v<decltype(ProcessTypedArraysFixed(aArg, processor)), int>,
+ "If the union can't contain non-typedarray members or null we can just "
+ "return the result of calling the lambda.");
+ }
+ void PassUnionWithTypedArraysOrNull(
+ const ArrayBufferViewOrArrayBufferOrNull& aArg) {
+ auto processor = [](const Span<uint8_t>& aData) -> int { return -1; };
+ static_assert(
+ std::is_same_v<decltype(ProcessTypedArraysFixed(aArg, processor)),
+ Maybe<int>>,
+ "If the union can contain non-typedarray members or null we need to "
+ "signal that with a Maybe<…> rv.");
+ }
+ void PassUnionWithString(JSContext*, const StringOrObject&);
+ void PassUnionWithEnum(JSContext*, const SupportedTypeOrObject&);
+ // void PassUnionWithCallback(JSContext*, const TestCallbackOrLong&);
+ void PassUnionWithObject(JSContext*, const ObjectOrLong&);
+
+ void PassUnionWithDefaultValue1(const DoubleOrString& arg);
+ void PassUnionWithDefaultValue2(const DoubleOrString& arg);
+ void PassUnionWithDefaultValue3(const DoubleOrString& arg);
+ void PassUnionWithDefaultValue4(const FloatOrString& arg);
+ void PassUnionWithDefaultValue5(const FloatOrString& arg);
+ void PassUnionWithDefaultValue6(const FloatOrString& arg);
+ void PassUnionWithDefaultValue7(const UnrestrictedDoubleOrString& arg);
+ void PassUnionWithDefaultValue8(const UnrestrictedDoubleOrString& arg);
+ void PassUnionWithDefaultValue9(const UnrestrictedDoubleOrString& arg);
+ void PassUnionWithDefaultValue10(const UnrestrictedDoubleOrString& arg);
+ void PassUnionWithDefaultValue11(const UnrestrictedFloatOrString& arg);
+ void PassUnionWithDefaultValue12(const UnrestrictedFloatOrString& arg);
+ void PassUnionWithDefaultValue13(const UnrestrictedFloatOrString& arg);
+ void PassUnionWithDefaultValue14(const DoubleOrByteString& arg);
+ void PassUnionWithDefaultValue15(const DoubleOrByteString& arg);
+ void PassUnionWithDefaultValue16(const DoubleOrByteString& arg);
+ void PassUnionWithDefaultValue17(const DoubleOrSupportedType& arg);
+ void PassUnionWithDefaultValue18(const DoubleOrSupportedType& arg);
+ void PassUnionWithDefaultValue19(const DoubleOrSupportedType& arg);
+ void PassUnionWithDefaultValue20(const DoubleOrUSVString& arg);
+ void PassUnionWithDefaultValue21(const DoubleOrUSVString& arg);
+ void PassUnionWithDefaultValue22(const DoubleOrUSVString& arg);
+ void PassUnionWithDefaultValue23(const DoubleOrUTF8String& arg);
+ void PassUnionWithDefaultValue24(const DoubleOrUTF8String& arg);
+ void PassUnionWithDefaultValue25(const DoubleOrUTF8String& arg);
+
+ void PassNullableUnionWithDefaultValue1(const Nullable<DoubleOrString>& arg);
+ void PassNullableUnionWithDefaultValue2(const Nullable<DoubleOrString>& arg);
+ void PassNullableUnionWithDefaultValue3(const Nullable<DoubleOrString>& arg);
+ void PassNullableUnionWithDefaultValue4(const Nullable<FloatOrString>& arg);
+ void PassNullableUnionWithDefaultValue5(const Nullable<FloatOrString>& arg);
+ void PassNullableUnionWithDefaultValue6(const Nullable<FloatOrString>& arg);
+ void PassNullableUnionWithDefaultValue7(
+ const Nullable<UnrestrictedDoubleOrString>& arg);
+ void PassNullableUnionWithDefaultValue8(
+ const Nullable<UnrestrictedDoubleOrString>& arg);
+ void PassNullableUnionWithDefaultValue9(
+ const Nullable<UnrestrictedDoubleOrString>& arg);
+ void PassNullableUnionWithDefaultValue10(
+ const Nullable<UnrestrictedFloatOrString>& arg);
+ void PassNullableUnionWithDefaultValue11(
+ const Nullable<UnrestrictedFloatOrString>& arg);
+ void PassNullableUnionWithDefaultValue12(
+ const Nullable<UnrestrictedFloatOrString>& arg);
+ void PassNullableUnionWithDefaultValue13(
+ const Nullable<DoubleOrByteString>& arg);
+ void PassNullableUnionWithDefaultValue14(
+ const Nullable<DoubleOrByteString>& arg);
+ void PassNullableUnionWithDefaultValue15(
+ const Nullable<DoubleOrByteString>& arg);
+ void PassNullableUnionWithDefaultValue16(
+ const Nullable<DoubleOrByteString>& arg);
+ void PassNullableUnionWithDefaultValue17(
+ const Nullable<DoubleOrSupportedType>& arg);
+ void PassNullableUnionWithDefaultValue18(
+ const Nullable<DoubleOrSupportedType>& arg);
+ void PassNullableUnionWithDefaultValue19(
+ const Nullable<DoubleOrSupportedType>& arg);
+ void PassNullableUnionWithDefaultValue20(
+ const Nullable<DoubleOrSupportedType>& arg);
+ void PassNullableUnionWithDefaultValue21(
+ const Nullable<DoubleOrUSVString>& arg);
+ void PassNullableUnionWithDefaultValue22(
+ const Nullable<DoubleOrUSVString>& arg);
+ void PassNullableUnionWithDefaultValue23(
+ const Nullable<DoubleOrUSVString>& arg);
+ void PassNullableUnionWithDefaultValue24(
+ const Nullable<DoubleOrUSVString>& arg);
+ void PassNullableUnionWithDefaultValue25(
+ const Nullable<DoubleOrUTF8String>& arg);
+ void PassNullableUnionWithDefaultValue26(
+ const Nullable<DoubleOrUTF8String>& arg);
+ void PassNullableUnionWithDefaultValue27(
+ const Nullable<DoubleOrUTF8String>& arg);
+ void PassNullableUnionWithDefaultValue28(
+ const Nullable<DoubleOrUTF8String>& arg);
+
+ void PassSequenceOfUnions(
+ const Sequence<OwningCanvasPatternOrCanvasGradient>&);
+ void PassSequenceOfUnions2(JSContext*, const Sequence<OwningObjectOrLong>&);
+ void PassVariadicUnion(const Sequence<OwningCanvasPatternOrCanvasGradient>&);
+
+ void PassSequenceOfNullableUnions(
+ const Sequence<Nullable<OwningCanvasPatternOrCanvasGradient>>&);
+ void PassVariadicNullableUnion(
+ const Sequence<Nullable<OwningCanvasPatternOrCanvasGradient>>&);
+ void PassRecordOfUnions(
+ const Record<nsString, OwningCanvasPatternOrCanvasGradient>&);
+ void PassRecordOfUnions2(JSContext*,
+ const Record<nsString, OwningObjectOrLong>&);
+
+ void PassUnionWithSequenceOfUnions(
+ const StringOrOnlyForUseInInnerUnionOrCanvasPatternSequence& arg);
+ void PassUnionWithRecordOfUnions(
+ const LongSequenceOrStringOnlyForUseInInnerUnionOrLongSequenceRecord&
+ arg);
+
+ void ReceiveUnion(OwningCanvasPatternOrCanvasGradient&);
+ void ReceiveUnion2(JSContext*, OwningObjectOrLong&);
+ void ReceiveUnionContainingNull(OwningCanvasPatternOrNullOrCanvasGradient&);
+ void ReceiveNullableUnion(Nullable<OwningCanvasPatternOrCanvasGradient>&);
+ void ReceiveNullableUnion2(JSContext*, Nullable<OwningObjectOrLong>&);
+ void ReceiveUnionWithUndefined(OwningUndefinedOrCanvasPattern&);
+ void ReceiveUnionWithNullableUndefined(OwningUndefinedOrNullOrCanvasPattern&);
+ void ReceiveUnionWithUndefinedAndNullable(
+ OwningUndefinedOrCanvasPatternOrNull&);
+ void ReceiveNullableUnionWithUndefined(
+ Nullable<OwningUndefinedOrCanvasPattern>&);
+
+ void GetWritableUnion(OwningCanvasPatternOrCanvasGradient&);
+ void SetWritableUnion(const CanvasPatternOrCanvasGradient&);
+ void GetWritableUnionContainingNull(
+ OwningCanvasPatternOrNullOrCanvasGradient&);
+ void SetWritableUnionContainingNull(
+ const CanvasPatternOrNullOrCanvasGradient&);
+ void GetWritableNullableUnion(Nullable<OwningCanvasPatternOrCanvasGradient>&);
+ void SetWritableNullableUnion(const Nullable<CanvasPatternOrCanvasGradient>&);
+ void GetWritableUnionWithUndefined(OwningUndefinedOrCanvasPattern&);
+ void SetWritableUnionWithUndefined(const UndefinedOrCanvasPattern&);
+ void GetWritableUnionWithNullableUndefined(
+ OwningUndefinedOrNullOrCanvasPattern&);
+ void SetWritableUnionWithNullableUndefined(
+ const UndefinedOrNullOrCanvasPattern&);
+ void GetWritableUnionWithUndefinedAndNullable(
+ OwningUndefinedOrCanvasPatternOrNull&);
+ void SetWritableUnionWithUndefinedAndNullable(
+ const UndefinedOrCanvasPatternOrNull&);
+ void GetWritableNullableUnionWithUndefined(
+ Nullable<OwningUndefinedOrCanvasPattern>&);
+ void SetWritableNullableUnionWithUndefined(
+ const Nullable<UndefinedOrCanvasPattern>&);
+
+ // Promise types
+ void PassPromise(Promise&);
+ void PassOptionalPromise(const Optional<OwningNonNull<Promise>>&);
+ void PassPromiseSequence(const Sequence<OwningNonNull<Promise>>&);
+ void PassPromiseRecord(const Record<nsString, RefPtr<Promise>>&);
+ Promise* ReceivePromise();
+ already_AddRefed<Promise> ReceiveAddrefedPromise();
+
+ // ObservableArray types
+ void OnDeleteBooleanObservableArray(bool, uint32_t, ErrorResult&);
+ void OnSetBooleanObservableArray(bool, uint32_t, ErrorResult&);
+ void OnDeleteObjectObservableArray(JSContext*, JS::Handle<JSObject*>,
+ uint32_t, ErrorResult&);
+ void OnSetObjectObservableArray(JSContext*, JS::Handle<JSObject*>, uint32_t,
+ ErrorResult&);
+ void OnDeleteAnyObservableArray(JSContext*, JS::Handle<JS::Value>, uint32_t,
+ ErrorResult&);
+ void OnSetAnyObservableArray(JSContext*, JS::Handle<JS::Value>, uint32_t,
+ ErrorResult&);
+ void OnDeleteInterfaceObservableArray(TestInterface*, uint32_t, ErrorResult&);
+ void OnSetInterfaceObservableArray(TestInterface*, uint32_t, ErrorResult&);
+ void OnDeleteNullableObservableArray(const Nullable<int>&, uint32_t,
+ ErrorResult&);
+ void OnSetNullableObservableArray(const Nullable<int>&, uint32_t,
+ ErrorResult&);
+
+ // binaryNames tests
+ void MethodRenamedTo();
+ void MethodRenamedTo(int8_t);
+ int8_t AttributeGetterRenamedTo();
+ int8_t AttributeRenamedTo();
+ void SetAttributeRenamedTo(int8_t);
+
+ // Dictionary tests
+ void PassDictionary(JSContext*, const Dict&);
+ void PassDictionary2(JSContext*, const Dict&);
+ void GetReadonlyDictionary(JSContext*, Dict&);
+ void GetReadonlyNullableDictionary(JSContext*, Nullable<Dict>&);
+ void GetWritableDictionary(JSContext*, Dict&);
+ void SetWritableDictionary(JSContext*, const Dict&);
+ void GetReadonlyFrozenDictionary(JSContext*, Dict&);
+ void GetReadonlyFrozenNullableDictionary(JSContext*, Nullable<Dict>&);
+ void GetWritableFrozenDictionary(JSContext*, Dict&);
+ void SetWritableFrozenDictionary(JSContext*, const Dict&);
+ void ReceiveDictionary(JSContext*, Dict&);
+ void ReceiveNullableDictionary(JSContext*, Nullable<Dict>&);
+ void PassOtherDictionary(const GrandparentDict&);
+ void PassSequenceOfDictionaries(JSContext*, const Sequence<Dict>&);
+ void PassRecordOfDictionaries(const Record<nsString, GrandparentDict>&);
+ void PassDictionaryOrLong(JSContext*, const Dict&);
+ void PassDictionaryOrLong(int32_t);
+ void PassDictContainingDict(JSContext*, const DictContainingDict&);
+ void PassDictContainingSequence(JSContext*, const DictContainingSequence&);
+ void ReceiveDictContainingSequence(JSContext*, DictContainingSequence&);
+ void PassVariadicDictionary(JSContext*, const Sequence<Dict>&);
+
+ // Typedefs
+ void ExerciseTypedefInterfaces1(TestInterface&);
+ already_AddRefed<TestInterface> ExerciseTypedefInterfaces2(TestInterface*);
+ void ExerciseTypedefInterfaces3(TestInterface&);
+
+ // Deprecated methods and attributes
+ int8_t DeprecatedAttribute();
+ void SetDeprecatedAttribute(int8_t);
+ int8_t DeprecatedMethod();
+ int8_t DeprecatedMethodWithContext(JSContext*, const JS::Value&);
+
+ // Static methods and attributes
+ static void StaticMethod(const GlobalObject&, bool);
+ static void StaticMethodWithContext(const GlobalObject&, const JS::Value&);
+ static bool StaticAttribute(const GlobalObject&);
+ static void SetStaticAttribute(const GlobalObject&, bool);
+ static void Assert(const GlobalObject&, bool);
+
+ // Deprecated static methods and attributes
+ static int8_t StaticDeprecatedAttribute(const GlobalObject&);
+ static void SetStaticDeprecatedAttribute(const GlobalObject&, int8_t);
+ static void StaticDeprecatedMethod(const GlobalObject&);
+ static void StaticDeprecatedMethodWithContext(const GlobalObject&,
+ const JS::Value&);
+
+ // Overload resolution tests
+ bool Overload1(TestInterface&);
+ TestInterface* Overload1(const nsAString&, TestInterface&);
+ void Overload2(TestInterface&);
+ void Overload2(JSContext*, const Dict&);
+ void Overload2(bool);
+ void Overload2(const nsAString&);
+ void Overload3(TestInterface&);
+ void Overload3(const TestCallback&);
+ void Overload3(bool);
+ void Overload4(TestInterface&);
+ void Overload4(TestCallbackInterface&);
+ void Overload4(const nsAString&);
+ void Overload5(int32_t);
+ void Overload5(TestEnum);
+ void Overload6(int32_t);
+ void Overload6(bool);
+ void Overload7(int32_t);
+ void Overload7(bool);
+ void Overload7(const nsCString&);
+ void Overload8(int32_t);
+ void Overload8(TestInterface&);
+ void Overload9(const Nullable<int32_t>&);
+ void Overload9(const nsAString&);
+ void Overload10(const Nullable<int32_t>&);
+ void Overload10(JSContext*, JS::Handle<JSObject*>);
+ void Overload11(int32_t);
+ void Overload11(const nsAString&);
+ void Overload12(int32_t);
+ void Overload12(const Nullable<bool>&);
+ void Overload13(const Nullable<int32_t>&);
+ void Overload13(bool);
+ void Overload14(const Optional<int32_t>&);
+ void Overload14(TestInterface&);
+ void Overload15(int32_t);
+ void Overload15(const Optional<NonNull<TestInterface>>&);
+ void Overload16(int32_t);
+ void Overload16(const Optional<TestInterface*>&);
+ void Overload17(const Sequence<int32_t>&);
+ void Overload17(const Record<nsString, int32_t>&);
+ void Overload18(const Record<nsString, nsString>&);
+ void Overload18(const Sequence<nsString>&);
+ void Overload19(const Sequence<int32_t>&);
+ void Overload19(JSContext*, const Dict&);
+ void Overload20(JSContext*, const Dict&);
+ void Overload20(const Sequence<int32_t>&);
+
+ // Variadic handling
+ void PassVariadicThirdArg(const nsAString&, int32_t,
+ const Sequence<OwningNonNull<TestInterface>>&);
+
+ // Conditionally exposed methods/attributes
+ bool Prefable1();
+ bool Prefable2();
+ bool Prefable3();
+ bool Prefable4();
+ bool Prefable5();
+ bool Prefable6();
+ bool Prefable7();
+ bool Prefable8();
+ bool Prefable9();
+ void Prefable10();
+ void Prefable11();
+ bool Prefable12();
+ void Prefable13();
+ bool Prefable14();
+ bool Prefable15();
+ bool Prefable16();
+ void Prefable17();
+ void Prefable18();
+ void Prefable19();
+ void Prefable20();
+ void Prefable21();
+ void Prefable22();
+ void Prefable23();
+ void Prefable24();
+
+ // Conditionally exposed methods/attributes involving [SecureContext]
+ bool ConditionalOnSecureContext1();
+ bool ConditionalOnSecureContext2();
+ bool ConditionalOnSecureContext3();
+ bool ConditionalOnSecureContext4();
+ void ConditionalOnSecureContext5();
+ void ConditionalOnSecureContext6();
+ void ConditionalOnSecureContext7();
+ void ConditionalOnSecureContext8();
+
+ bool ConditionalOnSecureContext9();
+ void ConditionalOnSecureContext10();
+
+ // Miscellania
+ int32_t AttrWithLenientThis();
+ void SetAttrWithLenientThis(int32_t);
+ uint32_t UnforgeableAttr();
+ uint32_t UnforgeableAttr2();
+ uint32_t UnforgeableMethod();
+ uint32_t UnforgeableMethod2();
+ void Stringify(nsString&);
+ void PassRenamedInterface(nsRenamedInterface&);
+ TestInterface* PutForwardsAttr();
+ TestInterface* PutForwardsAttr2();
+ TestInterface* PutForwardsAttr3();
+ void GetToJSONShouldSkipThis(JSContext*, JS::MutableHandle<JS::Value>);
+ void SetToJSONShouldSkipThis(JSContext*, JS::Rooted<JS::Value>&);
+ TestParentInterface* ToJSONShouldSkipThis2();
+ void SetToJSONShouldSkipThis2(TestParentInterface&);
+ TestCallbackInterface* ToJSONShouldSkipThis3();
+ void SetToJSONShouldSkipThis3(TestCallbackInterface&);
+ void ThrowingMethod(ErrorResult& aRv);
+ bool GetThrowingAttr(ErrorResult& aRv) const;
+ void SetThrowingAttr(bool arg, ErrorResult& aRv);
+ bool GetThrowingGetterAttr(ErrorResult& aRv) const;
+ void SetThrowingGetterAttr(bool arg);
+ bool ThrowingSetterAttr() const;
+ void SetThrowingSetterAttr(bool arg, ErrorResult& aRv);
+ void CanOOMMethod(OOMReporter& aRv);
+ bool GetCanOOMAttr(OOMReporter& aRv) const;
+ void SetCanOOMAttr(bool arg, OOMReporter& aRv);
+ bool GetCanOOMGetterAttr(OOMReporter& aRv) const;
+ void SetCanOOMGetterAttr(bool arg);
+ bool CanOOMSetterAttr() const;
+ void SetCanOOMSetterAttr(bool arg, OOMReporter& aRv);
+ void NeedsSubjectPrincipalMethod(nsIPrincipal&);
+ bool NeedsSubjectPrincipalAttr(nsIPrincipal&);
+ void SetNeedsSubjectPrincipalAttr(bool, nsIPrincipal&);
+ void NeedsCallerTypeMethod(CallerType);
+ bool NeedsCallerTypeAttr(CallerType);
+ void SetNeedsCallerTypeAttr(bool, CallerType);
+ void NeedsNonSystemSubjectPrincipalMethod(nsIPrincipal*);
+ bool NeedsNonSystemSubjectPrincipalAttr(nsIPrincipal*);
+ void SetNeedsNonSystemSubjectPrincipalAttr(bool, nsIPrincipal*);
+ void CeReactionsMethod();
+ void CeReactionsMethodOverload();
+ void CeReactionsMethodOverload(const nsAString&);
+ bool CeReactionsAttr() const;
+ void SetCeReactionsAttr(bool);
+ int16_t LegacyCall(const JS::Value&, uint32_t, TestInterface&);
+ void PassArgsWithDefaults(JSContext*, const Optional<int32_t>&,
+ TestInterface*, const Dict&, double,
+ const Optional<float>&);
+
+ void SetDashed_attribute(int8_t);
+ int8_t Dashed_attribute();
+ void Dashed_method();
+
+ bool NonEnumerableAttr() const;
+ void SetNonEnumerableAttr(bool);
+ void NonEnumerableMethod();
+
+ // Methods and properties imported via "includes"
+ bool MixedInProperty();
+ void SetMixedInProperty(bool);
+ void MixedInMethod();
+
+ // Test EnforceRange/Clamp
+ void DontEnforceRangeOrClamp(int8_t);
+ void DoEnforceRange(int8_t);
+ void DoEnforceRangeNullable(const Nullable<int8_t>&);
+ void DoClamp(int8_t);
+ void DoClampNullable(const Nullable<int8_t>&);
+ void SetEnforcedByte(int8_t);
+ int8_t EnforcedByte();
+ void SetEnforcedNullableByte(const Nullable<int8_t>&);
+ Nullable<int8_t> GetEnforcedNullableByte() const;
+ void SetClampedNullableByte(const Nullable<int8_t>&);
+ Nullable<int8_t> GetClampedNullableByte() const;
+ void SetClampedByte(int8_t);
+ int8_t ClampedByte();
+
+ // Test AllowShared
+ void SetAllowSharedArrayBufferViewTypedef(const ArrayBufferView&);
+ void GetAllowSharedArrayBufferViewTypedef(JSContext*,
+ JS::MutableHandle<JSObject*>);
+ void SetAllowSharedArrayBufferView(const ArrayBufferView&);
+ void GetAllowSharedArrayBufferView(JSContext*, JS::MutableHandle<JSObject*>);
+ void SetAllowSharedNullableArrayBufferView(const Nullable<ArrayBufferView>&);
+ void GetAllowSharedNullableArrayBufferView(JSContext*,
+ JS::MutableHandle<JSObject*>);
+ void SetAllowSharedArrayBuffer(const ArrayBuffer&);
+ void GetAllowSharedArrayBuffer(JSContext*, JS::MutableHandle<JSObject*>);
+ void SetAllowSharedNullableArrayBuffer(const Nullable<ArrayBuffer>&);
+ void GetAllowSharedNullableArrayBuffer(JSContext*,
+ JS::MutableHandle<JSObject*>);
+
+ void PassAllowSharedArrayBufferViewTypedef(const ArrayBufferView&);
+ void PassAllowSharedArrayBufferView(const ArrayBufferView&);
+ void PassAllowSharedNullableArrayBufferView(const Nullable<ArrayBufferView>&);
+ void PassAllowSharedArrayBuffer(const ArrayBuffer&);
+ void PassAllowSharedNullableArrayBuffer(const Nullable<ArrayBuffer>&);
+ void PassUnionArrayBuffer(const StringOrArrayBuffer& foo);
+ void PassUnionAllowSharedArrayBuffer(
+ const StringOrMaybeSharedArrayBuffer& foo);
+
+ private:
+ // We add signatures here that _could_ start matching if the codegen
+ // got data types wrong. That way if it ever does we'll have a call
+ // to these private deleted methods and compilation will fail.
+ void SetReadonlyByte(int8_t) = delete;
+ template <typename T>
+ void SetWritableByte(T) = delete;
+ template <typename T>
+ void PassByte(T) = delete;
+ void PassNullableByte(Nullable<int8_t>&) = delete;
+ template <typename T>
+ void PassOptionalByte(const Optional<T>&) = delete;
+ template <typename T>
+ void PassOptionalByteWithDefault(T) = delete;
+ void PassVariadicByte(Sequence<int8_t>&) = delete;
+
+ void SetReadonlyShort(int16_t) = delete;
+ template <typename T>
+ void SetWritableShort(T) = delete;
+ template <typename T>
+ void PassShort(T) = delete;
+ template <typename T>
+ void PassOptionalShort(const Optional<T>&) = delete;
+ template <typename T>
+ void PassOptionalShortWithDefault(T) = delete;
+
+ void SetReadonlyLong(int32_t) = delete;
+ template <typename T>
+ void SetWritableLong(T) = delete;
+ template <typename T>
+ void PassLong(T) = delete;
+ template <typename T>
+ void PassOptionalLong(const Optional<T>&) = delete;
+ template <typename T>
+ void PassOptionalLongWithDefault(T) = delete;
+
+ void SetReadonlyLongLong(int64_t) = delete;
+ template <typename T>
+ void SetWritableLongLong(T) = delete;
+ template <typename T>
+ void PassLongLong(T) = delete;
+ template <typename T>
+ void PassOptionalLongLong(const Optional<T>&) = delete;
+ template <typename T>
+ void PassOptionalLongLongWithDefault(T) = delete;
+
+ void SetReadonlyOctet(uint8_t) = delete;
+ template <typename T>
+ void SetWritableOctet(T) = delete;
+ template <typename T>
+ void PassOctet(T) = delete;
+ template <typename T>
+ void PassOptionalOctet(const Optional<T>&) = delete;
+ template <typename T>
+ void PassOptionalOctetWithDefault(T) = delete;
+
+ void SetReadonlyUnsignedShort(uint16_t) = delete;
+ template <typename T>
+ void SetWritableUnsignedShort(T) = delete;
+ template <typename T>
+ void PassUnsignedShort(T) = delete;
+ template <typename T>
+ void PassOptionalUnsignedShort(const Optional<T>&) = delete;
+ template <typename T>
+ void PassOptionalUnsignedShortWithDefault(T) = delete;
+
+ void SetReadonlyUnsignedLong(uint32_t) = delete;
+ template <typename T>
+ void SetWritableUnsignedLong(T) = delete;
+ template <typename T>
+ void PassUnsignedLong(T) = delete;
+ template <typename T>
+ void PassOptionalUnsignedLong(const Optional<T>&) = delete;
+ template <typename T>
+ void PassOptionalUnsignedLongWithDefault(T) = delete;
+
+ void SetReadonlyUnsignedLongLong(uint64_t) = delete;
+ template <typename T>
+ void SetWritableUnsignedLongLong(T) = delete;
+ template <typename T>
+ void PassUnsignedLongLong(T) = delete;
+ template <typename T>
+ void PassOptionalUnsignedLongLong(const Optional<T>&) = delete;
+ template <typename T>
+ void PassOptionalUnsignedLongLongWithDefault(T) = delete;
+
+ // Enforce that only const things are passed for sequences
+ void PassSequence(Sequence<int32_t>&) = delete;
+ void PassNullableSequence(Nullable<Sequence<int32_t>>&) = delete;
+ void PassOptionalNullableSequenceWithDefaultValue(
+ Nullable<Sequence<int32_t>>&) = delete;
+ void PassSequenceOfAny(JSContext*, Sequence<JS::Value>&) = delete;
+ void PassNullableSequenceOfAny(JSContext*,
+ Nullable<Sequence<JS::Value>>&) = delete;
+ void PassOptionalSequenceOfAny(JSContext*,
+ Optional<Sequence<JS::Value>>&) = delete;
+ void PassOptionalNullableSequenceOfAny(
+ JSContext*, Optional<Nullable<Sequence<JS::Value>>>&) = delete;
+ void PassOptionalSequenceOfAnyWithDefaultValue(
+ JSContext*, Nullable<Sequence<JS::Value>>&) = delete;
+ void PassSequenceOfSequenceOfAny(JSContext*,
+ Sequence<Sequence<JS::Value>>&) = delete;
+ void PassSequenceOfNullableSequenceOfAny(
+ JSContext*, Sequence<Nullable<Sequence<JS::Value>>>&) = delete;
+ void PassNullableSequenceOfNullableSequenceOfAny(
+ JSContext*, Nullable<Sequence<Nullable<Sequence<JS::Value>>>>&) = delete;
+ void PassOptionalNullableSequenceOfNullableSequenceOfAny(
+ JSContext*,
+ Optional<Nullable<Sequence<Nullable<Sequence<JS::Value>>>>>&) = delete;
+ void PassSequenceOfObject(JSContext*, Sequence<JSObject*>&) = delete;
+ void PassSequenceOfNullableObject(JSContext*, Sequence<JSObject*>&) = delete;
+ void PassOptionalNullableSequenceOfNullableSequenceOfObject(
+ JSContext*,
+ Optional<Nullable<Sequence<Nullable<Sequence<JSObject*>>>>>&) = delete;
+ void PassOptionalNullableSequenceOfNullableSequenceOfNullableObject(
+ JSContext*,
+ Optional<Nullable<Sequence<Nullable<Sequence<JSObject*>>>>>&) = delete;
+
+ // Enforce that only const things are passed for optional
+ void PassOptionalByte(Optional<int8_t>&) = delete;
+ void PassOptionalNullableByte(Optional<Nullable<int8_t>>&) = delete;
+ void PassOptionalShort(Optional<int16_t>&) = delete;
+ void PassOptionalLong(Optional<int32_t>&) = delete;
+ void PassOptionalLongLong(Optional<int64_t>&) = delete;
+ void PassOptionalOctet(Optional<uint8_t>&) = delete;
+ void PassOptionalUnsignedShort(Optional<uint16_t>&) = delete;
+ void PassOptionalUnsignedLong(Optional<uint32_t>&) = delete;
+ void PassOptionalUnsignedLongLong(Optional<uint64_t>&) = delete;
+ void PassOptionalSelf(Optional<TestInterface*>&) = delete;
+ void PassOptionalNonNullSelf(Optional<NonNull<TestInterface>>&) = delete;
+ void PassOptionalExternal(Optional<TestExternalInterface*>&) = delete;
+ void PassOptionalNonNullExternal(Optional<TestExternalInterface*>&) = delete;
+ void PassOptionalSequence(Optional<Sequence<int32_t>>&) = delete;
+ void PassOptionalNullableSequence(Optional<Nullable<Sequence<int32_t>>>&) =
+ delete;
+ void PassOptionalObjectSequence(
+ Optional<Sequence<OwningNonNull<TestInterface>>>&) = delete;
+ void PassOptionalArrayBuffer(Optional<ArrayBuffer>&) = delete;
+ void PassOptionalNullableArrayBuffer(Optional<ArrayBuffer*>&) = delete;
+ void PassOptionalEnum(Optional<TestEnum>&) = delete;
+ void PassOptionalCallback(JSContext*,
+ Optional<OwningNonNull<TestCallback>>&) = delete;
+ void PassOptionalNullableCallback(JSContext*,
+ Optional<RefPtr<TestCallback>>&) = delete;
+ void PassOptionalAny(Optional<JS::Handle<JS::Value>>&) = delete;
+
+ // And test that string stuff is always const
+ void PassString(nsAString&) = delete;
+ void PassNullableString(nsAString&) = delete;
+ void PassOptionalString(Optional<nsAString>&) = delete;
+ void PassOptionalStringWithDefaultValue(nsAString&) = delete;
+ void PassOptionalNullableString(Optional<nsAString>&) = delete;
+ void PassOptionalNullableStringWithDefaultValue(nsAString&) = delete;
+ void PassVariadicString(Sequence<nsString>&) = delete;
+
+ // cstrings should be const as well
+ void PassByteString(nsCString&) = delete;
+ void PassNullableByteString(nsCString&) = delete;
+ void PassOptionalByteString(Optional<nsCString>&) = delete;
+ void PassOptionalByteStringWithDefaultValue(nsCString&) = delete;
+ void PassOptionalNullableByteString(Optional<nsCString>&) = delete;
+ void PassOptionalNullableByteStringWithDefaultValue(nsCString&) = delete;
+ void PassVariadicByteString(Sequence<nsCString>&) = delete;
+
+ // cstrings should be const as well
+ void PassUTF8String(nsACString&) = delete;
+ void PassNullableUTF8String(nsACString&) = delete;
+ void PassOptionalUTF8String(Optional<nsACString>&) = delete;
+ void PassOptionalUTF8StringWithDefaultValue(nsACString&) = delete;
+ void PassOptionalNullableUTF8String(Optional<nsACString>&) = delete;
+ void PassOptionalNullableUTF8StringWithDefaultValue(nsACString&) = delete;
+ void PassVariadicUTF8String(Sequence<nsCString>&) = delete;
+
+ // Make sure dictionary arguments are always const
+ void PassDictionary(JSContext*, Dict&) = delete;
+ void PassOtherDictionary(GrandparentDict&) = delete;
+ void PassSequenceOfDictionaries(JSContext*, Sequence<Dict>&) = delete;
+ void PassDictionaryOrLong(JSContext*, Dict&) = delete;
+ void PassDictContainingDict(JSContext*, DictContainingDict&) = delete;
+ void PassDictContainingSequence(DictContainingSequence&) = delete;
+
+ // Make sure various nullable things are always const
+ void PassNullableEnum(Nullable<TestEnum>&) = delete;
+
+ // Make sure unions are always const
+ void PassUnion(JSContext*, ObjectOrLong& arg) = delete;
+ void PassUnionWithNullable(JSContext*, ObjectOrNullOrLong& arg) = delete;
+ void PassNullableUnion(JSContext*, Nullable<ObjectOrLong>&) = delete;
+ void PassOptionalUnion(JSContext*, Optional<ObjectOrLong>&) = delete;
+ void PassOptionalNullableUnion(JSContext*,
+ Optional<Nullable<ObjectOrLong>>&) = delete;
+ void PassOptionalNullableUnionWithDefaultValue(
+ JSContext*, Nullable<ObjectOrLong>&) = delete;
+
+ // Make sure variadics are const as needed
+ void PassVariadicAny(JSContext*, Sequence<JS::Value>&) = delete;
+ void PassVariadicObject(JSContext*, Sequence<JSObject*>&) = delete;
+ void PassVariadicNullableObject(JSContext*, Sequence<JSObject*>&) = delete;
+
+ // Ensure NonNull does not leak in
+ void PassSelf(NonNull<TestInterface>&) = delete;
+ void PassSelf(OwningNonNull<TestInterface>&) = delete;
+ void PassSelf(const NonNull<TestInterface>&) = delete;
+ void PassSelf(const OwningNonNull<TestInterface>&) = delete;
+ void PassCallbackInterface(OwningNonNull<TestCallbackInterface>&) = delete;
+ void PassCallbackInterface(const OwningNonNull<TestCallbackInterface>&) =
+ delete;
+ void PassCallbackInterface(NonNull<TestCallbackInterface>&) = delete;
+ void PassCallbackInterface(const NonNull<TestCallbackInterface>&) = delete;
+ void PassCallback(OwningNonNull<TestCallback>&) = delete;
+ void PassCallback(const OwningNonNull<TestCallback>&) = delete;
+ void PassCallback(NonNull<TestCallback>&) = delete;
+ void PassCallback(const NonNull<TestCallback>&) = delete;
+ void PassString(const NonNull<nsAString>&) = delete;
+ void PassString(NonNull<nsAString>&) = delete;
+ void PassString(const OwningNonNull<nsAString>&) = delete;
+ void PassString(OwningNonNull<nsAString>&) = delete;
+};
+
+class TestIndexedGetterInterface : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+
+ uint32_t IndexedGetter(uint32_t, bool&);
+ uint32_t IndexedGetter(uint32_t&) = delete;
+ uint32_t Item(uint32_t&);
+ uint32_t Item(uint32_t, bool&) = delete;
+ uint32_t Length();
+ void LegacyCall(JS::Handle<JS::Value>);
+ int32_t CachedAttr();
+ int32_t StoreInSlotAttr();
+};
+
+class TestNamedGetterInterface : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+
+ void NamedGetter(const nsAString&, bool&, nsAString&);
+ void GetSupportedNames(nsTArray<nsString>&);
+};
+
+class TestIndexedGetterAndSetterAndNamedGetterInterface
+ : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+
+ void NamedGetter(const nsAString&, bool&, nsAString&);
+ void GetSupportedNames(nsTArray<nsString>&);
+ int32_t IndexedGetter(uint32_t, bool&);
+ void IndexedSetter(uint32_t, int32_t);
+ uint32_t Length();
+};
+
+class TestIndexedAndNamedGetterInterface : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+
+ uint32_t IndexedGetter(uint32_t, bool&);
+ void NamedGetter(const nsAString&, bool&, nsAString&);
+ void NamedItem(const nsAString&, nsAString&);
+ uint32_t Length();
+ void GetSupportedNames(nsTArray<nsString>&);
+};
+
+class TestIndexedSetterInterface : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+
+ void IndexedSetter(uint32_t, const nsAString&);
+ void IndexedGetter(uint32_t, bool&, nsString&);
+ uint32_t Length();
+ void SetItem(uint32_t, const nsAString&);
+};
+
+class TestNamedSetterInterface : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+
+ void NamedSetter(const nsAString&, TestIndexedSetterInterface&);
+ TestIndexedSetterInterface* NamedGetter(const nsAString&, bool&);
+ void GetSupportedNames(nsTArray<nsString>&);
+};
+
+class TestIndexedAndNamedSetterInterface : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+
+ void IndexedSetter(uint32_t, TestIndexedSetterInterface&);
+ TestIndexedSetterInterface* IndexedGetter(uint32_t, bool&);
+ uint32_t Length();
+ void NamedSetter(const nsAString&, TestIndexedSetterInterface&);
+ TestIndexedSetterInterface* NamedGetter(const nsAString&, bool&);
+ void SetNamedItem(const nsAString&, TestIndexedSetterInterface&);
+ void GetSupportedNames(nsTArray<nsString>&);
+};
+
+class TestIndexedAndNamedGetterAndSetterInterface
+ : public TestIndexedSetterInterface {
+ public:
+ uint32_t IndexedGetter(uint32_t, bool&);
+ uint32_t Item(uint32_t);
+ void NamedGetter(const nsAString&, bool&, nsAString&);
+ void NamedItem(const nsAString&, nsAString&);
+ void IndexedSetter(uint32_t, int32_t&);
+ void IndexedSetter(uint32_t, const nsAString&) = delete;
+ void NamedSetter(const nsAString&, const nsAString&);
+ void Stringify(nsAString&);
+ uint32_t Length();
+ void GetSupportedNames(nsTArray<nsString>&);
+};
+
+class TestCppKeywordNamedMethodsInterface : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+
+ bool Continue();
+ bool Delete();
+ int32_t Volatile();
+};
+
+class TestNamedDeleterInterface : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+
+ void NamedDeleter(const nsAString&, bool&);
+ long NamedGetter(const nsAString&, bool&);
+ void GetSupportedNames(nsTArray<nsString>&);
+};
+
+class TestNamedDeleterWithRetvalInterface : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+
+ bool NamedDeleter(const nsAString&, bool&);
+ bool NamedDeleter(const nsAString&) = delete;
+ long NamedGetter(const nsAString&, bool&);
+ bool DelNamedItem(const nsAString&);
+ bool DelNamedItem(const nsAString&, bool&) = delete;
+ void GetSupportedNames(nsTArray<nsString>&);
+};
+
+class TestParentInterface : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+};
+
+class TestChildInterface : public TestParentInterface {};
+
+class TestDeprecatedInterface : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ static already_AddRefed<TestDeprecatedInterface> Constructor(
+ const GlobalObject&);
+
+ static void AlsoDeprecated(const GlobalObject&);
+
+ virtual nsISupports* GetParentObject();
+};
+
+class TestInterfaceWithPromiseConstructorArg : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ static already_AddRefed<TestInterfaceWithPromiseConstructorArg> Constructor(
+ const GlobalObject&, Promise&);
+
+ virtual nsISupports* GetParentObject();
+};
+
+class TestSecureContextInterface : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ static already_AddRefed<TestSecureContextInterface> Constructor(
+ const GlobalObject&, ErrorResult&);
+
+ static void AlsoSecureContext(const GlobalObject&);
+
+ virtual nsISupports* GetParentObject();
+};
+
+class TestNamespace {
+ public:
+ static bool Foo(const GlobalObject&);
+ static int32_t Bar(const GlobalObject&);
+ static void Baz(const GlobalObject&);
+};
+
+class TestRenamedNamespace {};
+
+class TestProtoObjectHackedNamespace {};
+
+class TestWorkerExposedInterface : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject to make binding codegen happy
+ nsISupports* GetParentObject();
+
+ void NeedsSubjectPrincipalMethod(nsIPrincipal&);
+ bool NeedsSubjectPrincipalAttr(nsIPrincipal&);
+ void SetNeedsSubjectPrincipalAttr(bool, nsIPrincipal&);
+ void NeedsCallerTypeMethod(CallerType);
+ bool NeedsCallerTypeAttr(CallerType);
+ void SetNeedsCallerTypeAttr(bool, CallerType);
+ void NeedsNonSystemSubjectPrincipalMethod(nsIPrincipal*);
+ bool NeedsNonSystemSubjectPrincipalAttr(nsIPrincipal*);
+ void SetNeedsNonSystemSubjectPrincipalAttr(bool, nsIPrincipal*);
+};
+
+class TestHTMLConstructorInterface : public nsGenericHTMLElement {
+ public:
+ virtual nsISupports* GetParentObject();
+};
+
+class TestThrowingConstructorInterface : public nsISupports,
+ public nsWrapperCache {
+ public:
+ static already_AddRefed<TestThrowingConstructorInterface> Constructor(
+ const GlobalObject&, ErrorResult&);
+ static already_AddRefed<TestThrowingConstructorInterface> Constructor(
+ const GlobalObject&, const nsAString&, ErrorResult&);
+ static already_AddRefed<TestThrowingConstructorInterface> Constructor(
+ const GlobalObject&, uint32_t, const Nullable<bool>&, ErrorResult&);
+ static already_AddRefed<TestThrowingConstructorInterface> Constructor(
+ const GlobalObject&, TestInterface*, ErrorResult&);
+ static already_AddRefed<TestThrowingConstructorInterface> Constructor(
+ const GlobalObject&, uint32_t, TestInterface&, ErrorResult&);
+
+ static already_AddRefed<TestThrowingConstructorInterface> Constructor(
+ const GlobalObject&, const ArrayBuffer&, ErrorResult&);
+ static already_AddRefed<TestThrowingConstructorInterface> Constructor(
+ const GlobalObject&, const Uint8Array&, ErrorResult&);
+ /* static
+ already_AddRefed<TestThrowingConstructorInterface>
+ Constructor(const GlobalObject&, uint32_t, uint32_t,
+ const TestInterfaceOrOnlyForUseInConstructor&, ErrorResult&);
+ */
+
+ virtual nsISupports* GetParentObject();
+};
+
+class TestCEReactionsInterface : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject and GetDocGroup to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+ DocGroup* GetDocGroup() const;
+
+ int32_t Item(uint32_t);
+ uint32_t Length() const;
+ int32_t IndexedGetter(uint32_t, bool&);
+ void IndexedSetter(uint32_t, int32_t);
+ void NamedDeleter(const nsAString&, bool&);
+ void NamedGetter(const nsAString&, bool&, nsString&);
+ void NamedSetter(const nsAString&, const nsAString&);
+ void GetSupportedNames(nsTArray<nsString>&);
+};
+
+class TestAttributesOnTypes : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+
+ // We need a GetParentObject and GetDocGroup to make binding codegen happy
+ virtual nsISupports* GetParentObject();
+
+ void Foo(uint8_t arg);
+ void Bar(uint8_t arg);
+ void Baz(const nsAString& arg);
+ uint8_t SomeAttr();
+ void SetSomeAttr(uint8_t);
+ void ArgWithAttr(uint8_t arg1, const Optional<uint8_t>& arg2);
+};
+
+class TestPrefConstructorForInterface : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+ virtual nsISupports* GetParentObject();
+
+ // Since only the constructor is under a pref,
+ // the generated constructor should check for the pref.
+ static already_AddRefed<TestPrefConstructorForInterface> Constructor(
+ const GlobalObject&);
+};
+
+class TestConstructorForPrefInterface : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+ virtual nsISupports* GetParentObject();
+
+ // Since the interface itself is under a Pref, there should be no
+ // check for the pref in the generated constructor.
+ static already_AddRefed<TestConstructorForPrefInterface> Constructor(
+ const GlobalObject&);
+};
+
+class TestPrefConstructorForDifferentPrefInterface : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+ virtual nsISupports* GetParentObject();
+
+ // Since the constructor's pref is different than the interface pref
+ // there should still be a check for the pref in the generated constructor.
+ static already_AddRefed<TestPrefConstructorForDifferentPrefInterface>
+ Constructor(const GlobalObject&);
+};
+
+class TestConstructorForSCInterface : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+ virtual nsISupports* GetParentObject();
+
+ // Since the interface itself is SecureContext, there should be no
+ // check for SecureContext in the constructor.
+ static already_AddRefed<TestConstructorForSCInterface> Constructor(
+ const GlobalObject&);
+};
+
+class TestSCConstructorForInterface : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+ virtual nsISupports* GetParentObject();
+
+ // Since the interface context is unspecified but the constructor is
+ // SecureContext, the generated constructor should check for SecureContext.
+ static already_AddRefed<TestSCConstructorForInterface> Constructor(
+ const GlobalObject&);
+};
+
+class TestConstructorForFuncInterface : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+ virtual nsISupports* GetParentObject();
+
+ // Since the interface has a Func attribute, but the constructor does not,
+ // the generated constructor should not check for the Func.
+ static already_AddRefed<TestConstructorForFuncInterface> Constructor(
+ const GlobalObject&);
+};
+
+class TestFuncConstructorForInterface : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+ virtual nsISupports* GetParentObject();
+
+ // Since the constructor has a Func attribute, but the interface does not,
+ // the generated constructor should check for the Func.
+ static already_AddRefed<TestFuncConstructorForInterface> Constructor(
+ const GlobalObject&);
+};
+
+class TestFuncConstructorForDifferentFuncInterface : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+ virtual nsISupports* GetParentObject();
+
+ // Since the constructor has a different Func attribute from the interface,
+ // the generated constructor should still check for its conditional func.
+ static already_AddRefed<TestFuncConstructorForDifferentFuncInterface>
+ Constructor(const GlobalObject&);
+};
+
+class TestPrefChromeOnlySCFuncConstructorForInterface : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_ISUPPORTS
+ virtual nsISupports* GetParentObject();
+
+ // There should be checks for all Pref/ChromeOnly/SecureContext/Func
+ // in the generated constructor.
+ static already_AddRefed<TestPrefChromeOnlySCFuncConstructorForInterface>
+ Constructor(const GlobalObject&);
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif /* TestBindingHeader_h */
diff --git a/dom/bindings/test/TestCImplementedInterface.h b/dom/bindings/test/TestCImplementedInterface.h
new file mode 100644
index 0000000000..6512911bd3
--- /dev/null
+++ b/dom/bindings/test/TestCImplementedInterface.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/.
+ */
+
+#ifndef TestCImplementedInterface_h
+#define TestCImplementedInterface_h
+
+#include "../TestJSImplGenBinding.h"
+
+namespace mozilla {
+namespace dom {
+
+class TestCImplementedInterface : public TestJSImplInterface {
+ public:
+ TestCImplementedInterface(JS::Handle<JSObject*> aJSImpl,
+ JS::Handle<JSObject*> aJSImplGlobal,
+ nsIGlobalObject* aParent)
+ : TestJSImplInterface(aJSImpl, aJSImplGlobal, aParent) {}
+};
+
+class TestCImplementedInterface2 : public nsISupports, public nsWrapperCache {
+ public:
+ explicit TestCImplementedInterface2(nsIGlobalObject* aParent) {}
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TestCImplementedInterface2)
+
+ // We need a GetParentObject to make binding codegen happy
+ nsISupports* GetParentObject();
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // TestCImplementedInterface_h
diff --git a/dom/bindings/test/TestCallback.webidl b/dom/bindings/test/TestCallback.webidl
new file mode 100644
index 0000000000..b4dfa83c53
--- /dev/null
+++ b/dom/bindings/test/TestCallback.webidl
@@ -0,0 +1,10 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+callback TestUnionArguments = undefined((DOMString or long) arg1,
+ (DOMString or long)? arg2,
+ optional (DOMString or long) arg3,
+ optional (DOMString or long)? arg4);
diff --git a/dom/bindings/test/TestCodeGen.webidl b/dom/bindings/test/TestCodeGen.webidl
new file mode 100644
index 0000000000..577be05920
--- /dev/null
+++ b/dom/bindings/test/TestCodeGen.webidl
@@ -0,0 +1,1537 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+typedef long myLong;
+typedef TestInterface AnotherNameForTestInterface;
+typedef TestInterface? NullableTestInterface;
+typedef CustomEventInit TestDictionaryTypedef;
+typedef ArrayBufferView ArrayBufferViewTypedef;
+typedef [AllowShared] ArrayBufferView AllowSharedArrayBufferViewTypedef;
+
+interface TestExternalInterface;
+
+// We need a pref name that's in StaticPrefList.h here.
+[Pref="dom.webidl.test1",
+ Exposed=Window]
+interface TestRenamedInterface {
+};
+
+[Exposed=Window]
+callback interface TestCallbackInterface {
+ readonly attribute long foo;
+ attribute DOMString bar;
+ undefined doSomething();
+ long doSomethingElse(DOMString arg, TestInterface otherArg);
+ undefined doSequenceLongArg(sequence<long> arg);
+ undefined doSequenceStringArg(sequence<DOMString> arg);
+ undefined doRecordLongArg(record<DOMString, long> arg);
+ sequence<long> getSequenceOfLong();
+ sequence<TestInterface> getSequenceOfInterfaces();
+ sequence<TestInterface>? getNullableSequenceOfInterfaces();
+ sequence<TestInterface?> getSequenceOfNullableInterfaces();
+ sequence<TestInterface?>? getNullableSequenceOfNullableInterfaces();
+ sequence<TestCallbackInterface> getSequenceOfCallbackInterfaces();
+ sequence<TestCallbackInterface>? getNullableSequenceOfCallbackInterfaces();
+ sequence<TestCallbackInterface?> getSequenceOfNullableCallbackInterfaces();
+ sequence<TestCallbackInterface?>? getNullableSequenceOfNullableCallbackInterfaces();
+ record<DOMString, long> getRecordOfLong();
+ Dict? getDictionary();
+ undefined passArrayBuffer(ArrayBuffer arg);
+ undefined passNullableArrayBuffer(ArrayBuffer? arg);
+ undefined passOptionalArrayBuffer(optional ArrayBuffer arg);
+ undefined passOptionalNullableArrayBuffer(optional ArrayBuffer? arg);
+ undefined passOptionalNullableArrayBufferWithDefaultValue(optional ArrayBuffer? arg= null);
+ undefined passArrayBufferView(ArrayBufferView arg);
+ undefined passInt8Array(Int8Array arg);
+ undefined passInt16Array(Int16Array arg);
+ undefined passInt32Array(Int32Array arg);
+ undefined passUint8Array(Uint8Array arg);
+ undefined passUint16Array(Uint16Array arg);
+ undefined passUint32Array(Uint32Array arg);
+ undefined passUint8ClampedArray(Uint8ClampedArray arg);
+ undefined passFloat32Array(Float32Array arg);
+ undefined passFloat64Array(Float64Array arg);
+ undefined passSequenceOfArrayBuffers(sequence<ArrayBuffer> arg);
+ undefined passSequenceOfNullableArrayBuffers(sequence<ArrayBuffer?> arg);
+ undefined passVariadicTypedArray(Float32Array... arg);
+ undefined passVariadicNullableTypedArray(Float32Array?... arg);
+ Uint8Array receiveUint8Array();
+ attribute Uint8Array uint8ArrayAttr;
+ Promise<undefined> receivePromise();
+};
+
+[Exposed=Window]
+callback interface TestSingleOperationCallbackInterface {
+ TestInterface doSomething(short arg, sequence<double> anotherArg);
+};
+
+enum TestEnum {
+ "1",
+ "a",
+ "b",
+ "1-2",
+ "2d-array"
+};
+
+callback TestCallback = undefined();
+[TreatNonCallableAsNull] callback TestTreatAsNullCallback = undefined();
+
+// Callback return value tests
+callback TestIntegerReturn = long();
+callback TestNullableIntegerReturn = long?();
+callback TestBooleanReturn = boolean();
+callback TestFloatReturn = float();
+callback TestStringReturn = DOMString(long arg);
+callback TestEnumReturn = TestEnum();
+callback TestInterfaceReturn = TestInterface();
+callback TestNullableInterfaceReturn = TestInterface?();
+callback TestExternalInterfaceReturn = TestExternalInterface();
+callback TestNullableExternalInterfaceReturn = TestExternalInterface?();
+callback TestCallbackInterfaceReturn = TestCallbackInterface();
+callback TestNullableCallbackInterfaceReturn = TestCallbackInterface?();
+callback TestCallbackReturn = TestCallback();
+callback TestNullableCallbackReturn = TestCallback?();
+callback TestObjectReturn = object();
+callback TestNullableObjectReturn = object?();
+callback TestTypedArrayReturn = ArrayBuffer();
+callback TestNullableTypedArrayReturn = ArrayBuffer?();
+callback TestSequenceReturn = sequence<boolean>();
+callback TestNullableSequenceReturn = sequence<boolean>?();
+// Callback argument tests
+callback TestIntegerArguments = sequence<long>(long arg1, long? arg2,
+ sequence<long> arg3,
+ sequence<long?>? arg4);
+callback TestInterfaceArguments = undefined(TestInterface arg1,
+ TestInterface? arg2,
+ TestExternalInterface arg3,
+ TestExternalInterface? arg4,
+ TestCallbackInterface arg5,
+ TestCallbackInterface? arg6,
+ sequence<TestInterface> arg7,
+ sequence<TestInterface?>? arg8,
+ sequence<TestExternalInterface> arg9,
+ sequence<TestExternalInterface?>? arg10,
+ sequence<TestCallbackInterface> arg11,
+ sequence<TestCallbackInterface?>? arg12);
+callback TestStringEnumArguments = undefined(DOMString myString, DOMString? nullString,
+ TestEnum myEnum);
+callback TestObjectArguments = undefined(object anObj, object? anotherObj,
+ ArrayBuffer buf, ArrayBuffer? buf2);
+callback TestOptionalArguments = undefined(optional DOMString aString,
+ optional object something,
+ optional sequence<TestInterface> aSeq,
+ optional TestInterface? anInterface,
+ optional TestInterface anotherInterface,
+ optional long aLong);
+// Callback constructor return value tests
+callback constructor TestUndefinedConstruction = undefined(TestDictionaryTypedef arg);
+callback constructor TestIntegerConstruction = unsigned long();
+callback constructor TestBooleanConstruction = boolean(any arg1,
+ optional any arg2);
+callback constructor TestFloatConstruction = unrestricted float(optional object arg1,
+ optional TestDictionaryTypedef arg2);
+callback constructor TestStringConstruction = DOMString(long? arg);
+callback constructor TestEnumConstruction = TestEnum(any... arg);
+callback constructor TestInterfaceConstruction = TestInterface();
+callback constructor TestExternalInterfaceConstruction = TestExternalInterface();
+callback constructor TestCallbackInterfaceConstruction = TestCallbackInterface();
+callback constructor TestCallbackConstruction = TestCallback();
+callback constructor TestObjectConstruction = object();
+callback constructor TestTypedArrayConstruction = ArrayBuffer();
+callback constructor TestSequenceConstruction = sequence<boolean>();
+// If you add a new test callback, add it to the forceCallbackGeneration
+// method on TestInterface so it actually gets tested.
+
+TestInterface includes InterfaceMixin;
+
+// This interface is only for use in the constructor below
+[Exposed=Window]
+interface OnlyForUseInConstructor {
+};
+
+// This enum is only for use in inner unions below
+enum OnlyForUseInInnerUnion {
+ "1",
+};
+
+[LegacyFactoryFunction=Test,
+ LegacyFactoryFunction=Test(DOMString str),
+ LegacyFactoryFunction=Test2(DictForConstructor dict, any any1, object obj1,
+ object? obj2, sequence<Dict> seq, optional any any2,
+ optional object obj3, optional object? obj4),
+ LegacyFactoryFunction=Test3((long or record<DOMString, any>) arg1),
+ LegacyFactoryFunction=Test4(record<DOMString, record<DOMString, any>> arg1),
+ LegacyFactoryFunction=Test5(record<DOMString, sequence<record<DOMString, record<DOMString, sequence<sequence<any>>>>>> arg1),
+ LegacyFactoryFunction=Test6(sequence<record<ByteString, sequence<sequence<record<ByteString, record<USVString, any>>>>>> arg1),
+ Exposed=Window]
+interface TestInterface {
+ constructor();
+ constructor(DOMString str);
+ constructor(unsigned long num, boolean? boolArg);
+ constructor(TestInterface? iface);
+ constructor(unsigned long arg1, TestInterface iface);
+ constructor(ArrayBuffer arrayBuf);
+ constructor(Uint8Array typedArr);
+ // constructor(long arg1, long arg2, (TestInterface or OnlyForUseInConstructor) arg3);
+
+ // Integer types
+ // XXXbz add tests for throwing versions of all the integer stuff
+ readonly attribute byte readonlyByte;
+ attribute byte writableByte;
+ undefined passByte(byte arg);
+ byte receiveByte();
+ undefined passOptionalByte(optional byte arg);
+ undefined passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
+ undefined passOptionalByteWithDefault(optional byte arg = 0);
+ undefined passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
+ undefined passNullableByte(byte? arg);
+ undefined passOptionalNullableByte(optional byte? arg);
+ undefined passVariadicByte(byte... arg);
+ [StoreInSlot, Pure]
+ readonly attribute byte cachedByte;
+ [StoreInSlot, Constant]
+ readonly attribute byte cachedConstantByte;
+ [StoreInSlot, Pure]
+ attribute byte cachedWritableByte;
+ [Affects=Nothing]
+ attribute byte sideEffectFreeByte;
+ [Affects=Nothing, DependsOn=DOMState]
+ attribute byte domDependentByte;
+ [Affects=Nothing, DependsOn=Nothing]
+ readonly attribute byte constantByte;
+ [DependsOn=DeviceState, Affects=Nothing]
+ readonly attribute byte deviceStateDependentByte;
+ [Affects=Nothing]
+ byte returnByteSideEffectFree();
+ [Affects=Nothing, DependsOn=DOMState]
+ byte returnDOMDependentByte();
+ [Affects=Nothing, DependsOn=Nothing]
+ byte returnConstantByte();
+ [DependsOn=DeviceState, Affects=Nothing]
+ byte returnDeviceStateDependentByte();
+
+ readonly attribute short readonlyShort;
+ attribute short writableShort;
+ undefined passShort(short arg);
+ short receiveShort();
+ undefined passOptionalShort(optional short arg);
+ undefined passOptionalShortWithDefault(optional short arg = 5);
+
+ readonly attribute long readonlyLong;
+ attribute long writableLong;
+ undefined passLong(long arg);
+ long receiveLong();
+ undefined passOptionalLong(optional long arg);
+ undefined passOptionalLongWithDefault(optional long arg = 7);
+
+ readonly attribute long long readonlyLongLong;
+ attribute long long writableLongLong;
+ undefined passLongLong(long long arg);
+ long long receiveLongLong();
+ undefined passOptionalLongLong(optional long long arg);
+ undefined passOptionalLongLongWithDefault(optional long long arg = -12);
+
+ readonly attribute octet readonlyOctet;
+ attribute octet writableOctet;
+ undefined passOctet(octet arg);
+ octet receiveOctet();
+ undefined passOptionalOctet(optional octet arg);
+ undefined passOptionalOctetWithDefault(optional octet arg = 19);
+
+ readonly attribute unsigned short readonlyUnsignedShort;
+ attribute unsigned short writableUnsignedShort;
+ undefined passUnsignedShort(unsigned short arg);
+ unsigned short receiveUnsignedShort();
+ undefined passOptionalUnsignedShort(optional unsigned short arg);
+ undefined passOptionalUnsignedShortWithDefault(optional unsigned short arg = 2);
+
+ readonly attribute unsigned long readonlyUnsignedLong;
+ attribute unsigned long writableUnsignedLong;
+ undefined passUnsignedLong(unsigned long arg);
+ unsigned long receiveUnsignedLong();
+ undefined passOptionalUnsignedLong(optional unsigned long arg);
+ undefined passOptionalUnsignedLongWithDefault(optional unsigned long arg = 6);
+
+ readonly attribute unsigned long long readonlyUnsignedLongLong;
+ attribute unsigned long long writableUnsignedLongLong;
+ undefined passUnsignedLongLong(unsigned long long arg);
+ unsigned long long receiveUnsignedLongLong();
+ undefined passOptionalUnsignedLongLong(optional unsigned long long arg);
+ undefined passOptionalUnsignedLongLongWithDefault(optional unsigned long long arg = 17);
+
+ attribute float writableFloat;
+ attribute unrestricted float writableUnrestrictedFloat;
+ attribute float? writableNullableFloat;
+ attribute unrestricted float? writableNullableUnrestrictedFloat;
+ attribute double writableDouble;
+ attribute unrestricted double writableUnrestrictedDouble;
+ attribute double? writableNullableDouble;
+ attribute unrestricted double? writableNullableUnrestrictedDouble;
+ undefined passFloat(float arg1, unrestricted float arg2,
+ float? arg3, unrestricted float? arg4,
+ double arg5, unrestricted double arg6,
+ double? arg7, unrestricted double? arg8,
+ sequence<float> arg9, sequence<unrestricted float> arg10,
+ sequence<float?> arg11, sequence<unrestricted float?> arg12,
+ sequence<double> arg13, sequence<unrestricted double> arg14,
+ sequence<double?> arg15, sequence<unrestricted double?> arg16);
+ [LenientFloat]
+ undefined passLenientFloat(float arg1, unrestricted float arg2,
+ float? arg3, unrestricted float? arg4,
+ double arg5, unrestricted double arg6,
+ double? arg7, unrestricted double? arg8,
+ sequence<float> arg9,
+ sequence<unrestricted float> arg10,
+ sequence<float?> arg11,
+ sequence<unrestricted float?> arg12,
+ sequence<double> arg13,
+ sequence<unrestricted double> arg14,
+ sequence<double?> arg15,
+ sequence<unrestricted double?> arg16);
+ [LenientFloat]
+ attribute float lenientFloatAttr;
+ [LenientFloat]
+ attribute double lenientDoubleAttr;
+
+ undefined passUnrestricted(optional unrestricted float arg1 = 0,
+ optional unrestricted float arg2 = Infinity,
+ optional unrestricted float arg3 = -Infinity,
+ optional unrestricted float arg4 = NaN,
+ optional unrestricted double arg5 = 0,
+ optional unrestricted double arg6 = Infinity,
+ optional unrestricted double arg7 = -Infinity,
+ optional unrestricted double arg8 = NaN);
+
+ // Castable interface types
+ // XXXbz add tests for throwing versions of all the castable interface stuff
+ TestInterface receiveSelf();
+ TestInterface? receiveNullableSelf();
+ TestInterface receiveWeakSelf();
+ TestInterface? receiveWeakNullableSelf();
+ undefined passSelf(TestInterface arg);
+ undefined passNullableSelf(TestInterface? arg);
+ attribute TestInterface nonNullSelf;
+ attribute TestInterface? nullableSelf;
+ [Cached, Pure]
+ readonly attribute TestInterface cachedSelf;
+ // Optional arguments
+ undefined passOptionalSelf(optional TestInterface? arg);
+ undefined passOptionalNonNullSelf(optional TestInterface arg);
+ undefined passOptionalSelfWithDefault(optional TestInterface? arg = null);
+
+ // Non-wrapper-cache interface types
+ [NewObject]
+ TestNonWrapperCacheInterface receiveNonWrapperCacheInterface();
+ [NewObject]
+ TestNonWrapperCacheInterface? receiveNullableNonWrapperCacheInterface();
+ [NewObject]
+ sequence<TestNonWrapperCacheInterface> receiveNonWrapperCacheInterfaceSequence();
+ [NewObject]
+ sequence<TestNonWrapperCacheInterface?> receiveNullableNonWrapperCacheInterfaceSequence();
+ [NewObject]
+ sequence<TestNonWrapperCacheInterface>? receiveNonWrapperCacheInterfaceNullableSequence();
+ [NewObject]
+ sequence<TestNonWrapperCacheInterface?>? receiveNullableNonWrapperCacheInterfaceNullableSequence();
+
+ // External interface types
+ TestExternalInterface receiveExternal();
+ TestExternalInterface? receiveNullableExternal();
+ TestExternalInterface receiveWeakExternal();
+ TestExternalInterface? receiveWeakNullableExternal();
+ undefined passExternal(TestExternalInterface arg);
+ undefined passNullableExternal(TestExternalInterface? arg);
+ attribute TestExternalInterface nonNullExternal;
+ attribute TestExternalInterface? nullableExternal;
+ // Optional arguments
+ undefined passOptionalExternal(optional TestExternalInterface? arg);
+ undefined passOptionalNonNullExternal(optional TestExternalInterface arg);
+ undefined passOptionalExternalWithDefault(optional TestExternalInterface? arg = null);
+
+ // Callback interface types
+ TestCallbackInterface receiveCallbackInterface();
+ TestCallbackInterface? receiveNullableCallbackInterface();
+ TestCallbackInterface receiveWeakCallbackInterface();
+ TestCallbackInterface? receiveWeakNullableCallbackInterface();
+ undefined passCallbackInterface(TestCallbackInterface arg);
+ undefined passNullableCallbackInterface(TestCallbackInterface? arg);
+ attribute TestCallbackInterface nonNullCallbackInterface;
+ attribute TestCallbackInterface? nullableCallbackInterface;
+ // Optional arguments
+ undefined passOptionalCallbackInterface(optional TestCallbackInterface? arg);
+ undefined passOptionalNonNullCallbackInterface(optional TestCallbackInterface arg);
+ undefined passOptionalCallbackInterfaceWithDefault(optional TestCallbackInterface? arg = null);
+
+ // Sequence types
+ [Cached, Pure]
+ readonly attribute sequence<long> readonlySequence;
+ [Cached, Pure]
+ readonly attribute sequence<Dict> readonlySequenceOfDictionaries;
+ [Cached, Pure]
+ readonly attribute sequence<Dict>? readonlyNullableSequenceOfDictionaries;
+ [Cached, Pure, Frozen]
+ readonly attribute sequence<Dict> readonlyFrozenSequence;
+ [Cached, Pure, Frozen]
+ readonly attribute sequence<Dict>? readonlyFrozenNullableSequence;
+ sequence<long> receiveSequence();
+ sequence<long>? receiveNullableSequence();
+ sequence<long?> receiveSequenceOfNullableInts();
+ sequence<long?>? receiveNullableSequenceOfNullableInts();
+ undefined passSequence(sequence<long> arg);
+ undefined passNullableSequence(sequence<long>? arg);
+ undefined passSequenceOfNullableInts(sequence<long?> arg);
+ undefined passOptionalSequenceOfNullableInts(optional sequence<long?> arg);
+ undefined passOptionalNullableSequenceOfNullableInts(optional sequence<long?>? arg);
+ sequence<TestInterface> receiveCastableObjectSequence();
+ sequence<TestCallbackInterface> receiveCallbackObjectSequence();
+ sequence<TestInterface?> receiveNullableCastableObjectSequence();
+ sequence<TestCallbackInterface?> receiveNullableCallbackObjectSequence();
+ sequence<TestInterface>? receiveCastableObjectNullableSequence();
+ sequence<TestInterface?>? receiveNullableCastableObjectNullableSequence();
+ sequence<TestInterface> receiveWeakCastableObjectSequence();
+ sequence<TestInterface?> receiveWeakNullableCastableObjectSequence();
+ sequence<TestInterface>? receiveWeakCastableObjectNullableSequence();
+ sequence<TestInterface?>? receiveWeakNullableCastableObjectNullableSequence();
+ undefined passCastableObjectSequence(sequence<TestInterface> arg);
+ undefined passNullableCastableObjectSequence(sequence<TestInterface?> arg);
+ undefined passCastableObjectNullableSequence(sequence<TestInterface>? arg);
+ undefined passNullableCastableObjectNullableSequence(sequence<TestInterface?>? arg);
+ undefined passOptionalSequence(optional sequence<long> arg);
+ undefined passOptionalSequenceWithDefaultValue(optional sequence<long> arg = []);
+ undefined passOptionalNullableSequence(optional sequence<long>? arg);
+ undefined passOptionalNullableSequenceWithDefaultValue(optional sequence<long>? arg = null);
+ undefined passOptionalNullableSequenceWithDefaultValue2(optional sequence<long>? arg = []);
+ undefined passOptionalObjectSequence(optional sequence<TestInterface> arg);
+ undefined passExternalInterfaceSequence(sequence<TestExternalInterface> arg);
+ undefined passNullableExternalInterfaceSequence(sequence<TestExternalInterface?> arg);
+
+ sequence<DOMString> receiveStringSequence();
+ undefined passStringSequence(sequence<DOMString> arg);
+
+ sequence<ByteString> receiveByteStringSequence();
+ undefined passByteStringSequence(sequence<ByteString> arg);
+
+ sequence<UTF8String> receiveUTF8StringSequence();
+ undefined passUTF8StringSequence(sequence<UTF8String> arg);
+
+ sequence<any> receiveAnySequence();
+ sequence<any>? receiveNullableAnySequence();
+ sequence<sequence<any>> receiveAnySequenceSequence();
+
+ sequence<object> receiveObjectSequence();
+ sequence<object?> receiveNullableObjectSequence();
+
+ undefined passSequenceOfSequences(sequence<sequence<long>> arg);
+ undefined passSequenceOfSequencesOfSequences(sequence<sequence<sequence<long>>> arg);
+ sequence<sequence<long>> receiveSequenceOfSequences();
+ sequence<sequence<sequence<long>>> receiveSequenceOfSequencesOfSequences();
+
+ // record types
+ undefined passRecord(record<DOMString, long> arg);
+ undefined passNullableRecord(record<DOMString, long>? arg);
+ undefined passRecordOfNullableInts(record<DOMString, long?> arg);
+ undefined passOptionalRecordOfNullableInts(optional record<DOMString, long?> arg);
+ undefined passOptionalNullableRecordOfNullableInts(optional record<DOMString, long?>? arg);
+ undefined passCastableObjectRecord(record<DOMString, TestInterface> arg);
+ undefined passNullableCastableObjectRecord(record<DOMString, TestInterface?> arg);
+ undefined passCastableObjectNullableRecord(record<DOMString, TestInterface>? arg);
+ undefined passNullableCastableObjectNullableRecord(record<DOMString, TestInterface?>? arg);
+ undefined passOptionalRecord(optional record<DOMString, long> arg);
+ undefined passOptionalNullableRecord(optional record<DOMString, long>? arg);
+ undefined passOptionalNullableRecordWithDefaultValue(optional record<DOMString, long>? arg = null);
+ undefined passOptionalObjectRecord(optional record<DOMString, TestInterface> arg);
+ undefined passExternalInterfaceRecord(record<DOMString, TestExternalInterface> arg);
+ undefined passNullableExternalInterfaceRecord(record<DOMString, TestExternalInterface?> arg);
+ undefined passStringRecord(record<DOMString, DOMString> arg);
+ undefined passByteStringRecord(record<DOMString, ByteString> arg);
+ undefined passUTF8StringRecord(record<DOMString, UTF8String> arg);
+ undefined passRecordOfRecords(record<DOMString, record<DOMString, long>> arg);
+ record<DOMString, long> receiveRecord();
+ record<DOMString, long>? receiveNullableRecord();
+ record<DOMString, long?> receiveRecordOfNullableInts();
+ record<DOMString, long?>? receiveNullableRecordOfNullableInts();
+ record<DOMString, record<DOMString, long>> receiveRecordOfRecords();
+ record<DOMString, any> receiveAnyRecord();
+
+ // Typed array types
+ undefined passArrayBuffer(ArrayBuffer arg);
+ undefined passNullableArrayBuffer(ArrayBuffer? arg);
+ undefined passOptionalArrayBuffer(optional ArrayBuffer arg);
+ undefined passOptionalNullableArrayBuffer(optional ArrayBuffer? arg);
+ undefined passOptionalNullableArrayBufferWithDefaultValue(optional ArrayBuffer? arg= null);
+ undefined passArrayBufferView(ArrayBufferView arg);
+ undefined passInt8Array(Int8Array arg);
+ undefined passInt16Array(Int16Array arg);
+ undefined passInt32Array(Int32Array arg);
+ undefined passUint8Array(Uint8Array arg);
+ undefined passUint16Array(Uint16Array arg);
+ undefined passUint32Array(Uint32Array arg);
+ undefined passUint8ClampedArray(Uint8ClampedArray arg);
+ undefined passFloat32Array(Float32Array arg);
+ undefined passFloat64Array(Float64Array arg);
+ undefined passSequenceOfArrayBuffers(sequence<ArrayBuffer> arg);
+ undefined passSequenceOfNullableArrayBuffers(sequence<ArrayBuffer?> arg);
+ undefined passRecordOfArrayBuffers(record<DOMString, ArrayBuffer> arg);
+ undefined passRecordOfNullableArrayBuffers(record<DOMString, ArrayBuffer?> arg);
+ undefined passVariadicTypedArray(Float32Array... arg);
+ undefined passVariadicNullableTypedArray(Float32Array?... arg);
+ Uint8Array receiveUint8Array();
+ attribute Uint8Array uint8ArrayAttr;
+
+ // DOMString types
+ undefined passString(DOMString arg);
+ undefined passNullableString(DOMString? arg);
+ undefined passOptionalString(optional DOMString arg);
+ undefined passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
+ undefined passOptionalNullableString(optional DOMString? arg);
+ undefined passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
+ undefined passVariadicString(DOMString... arg);
+ DOMString receiveString();
+
+ // ByteString types
+ undefined passByteString(ByteString arg);
+ undefined passNullableByteString(ByteString? arg);
+ undefined passOptionalByteString(optional ByteString arg);
+ undefined passOptionalByteStringWithDefaultValue(optional ByteString arg = "abc");
+ undefined passOptionalNullableByteString(optional ByteString? arg);
+ undefined passOptionalNullableByteStringWithDefaultValue(optional ByteString? arg = null);
+ undefined passVariadicByteString(ByteString... arg);
+ undefined passOptionalUnionByteString(optional (ByteString or long) arg);
+ undefined passOptionalUnionByteStringWithDefaultValue(optional (ByteString or long) arg = "abc");
+
+ // UTF8String types
+ undefined passUTF8String(UTF8String arg);
+ undefined passNullableUTF8String(UTF8String? arg);
+ undefined passOptionalUTF8String(optional UTF8String arg);
+ undefined passOptionalUTF8StringWithDefaultValue(optional UTF8String arg = "abc");
+ undefined passOptionalNullableUTF8String(optional UTF8String? arg);
+ undefined passOptionalNullableUTF8StringWithDefaultValue(optional UTF8String? arg = null);
+ undefined passVariadicUTF8String(UTF8String... arg);
+ undefined passOptionalUnionUTF8String(optional (UTF8String or long) arg);
+ undefined passOptionalUnionUTF8StringWithDefaultValue(optional (UTF8String or long) arg = "abc");
+
+ // USVString types
+ undefined passUSVS(USVString arg);
+ undefined passNullableUSVS(USVString? arg);
+ undefined passOptionalUSVS(optional USVString arg);
+ undefined passOptionalUSVSWithDefaultValue(optional USVString arg = "abc");
+ undefined passOptionalNullableUSVS(optional USVString? arg);
+ undefined passOptionalNullableUSVSWithDefaultValue(optional USVString? arg = null);
+ undefined passVariadicUSVS(USVString... arg);
+ USVString receiveUSVS();
+
+ // JSString types
+ undefined passJSString(JSString arg);
+ // undefined passNullableJSString(JSString? arg); // NOT SUPPORTED YET
+ // undefined passOptionalJSString(optional JSString arg); // NOT SUPPORTED YET
+ undefined passOptionalJSStringWithDefaultValue(optional JSString arg = "abc");
+ // undefined passOptionalNullableJSString(optional JSString? arg); // NOT SUPPORTED YET
+ // undefined passOptionalNullableJSStringWithDefaultValue(optional JSString? arg = null); // NOT SUPPORTED YET
+ // undefined passVariadicJSString(JSString... arg); // NOT SUPPORTED YET
+ // undefined passRecordOfJSString(record<DOMString, JSString> arg); // NOT SUPPORTED YET
+ // undefined passSequenceOfJSString(sequence<JSString> arg); // NOT SUPPORTED YET
+ // undefined passUnionJSString((JSString or long) arg); // NOT SUPPORTED YET
+ JSString receiveJSString();
+ // sequence<JSString> receiveJSStringSequence(); // NOT SUPPORTED YET
+ // (JSString or long) receiveJSStringUnion(); // NOT SUPPORTED YET
+ // record<DOMString, JSString> receiveJSStringRecord(); // NOT SUPPORTED YET
+ readonly attribute JSString readonlyJSStringAttr;
+ attribute JSString jsStringAttr;
+
+ // Enumerated types
+ undefined passEnum(TestEnum arg);
+ undefined passNullableEnum(TestEnum? arg);
+ undefined passOptionalEnum(optional TestEnum arg);
+ undefined passEnumWithDefault(optional TestEnum arg = "a");
+ undefined passOptionalNullableEnum(optional TestEnum? arg);
+ undefined passOptionalNullableEnumWithDefaultValue(optional TestEnum? arg = null);
+ undefined passOptionalNullableEnumWithDefaultValue2(optional TestEnum? arg = "a");
+ TestEnum receiveEnum();
+ TestEnum? receiveNullableEnum();
+ attribute TestEnum enumAttribute;
+ readonly attribute TestEnum readonlyEnumAttribute;
+
+ // Callback types
+ undefined passCallback(TestCallback arg);
+ undefined passNullableCallback(TestCallback? arg);
+ undefined passOptionalCallback(optional TestCallback arg);
+ undefined passOptionalNullableCallback(optional TestCallback? arg);
+ undefined passOptionalNullableCallbackWithDefaultValue(optional TestCallback? arg = null);
+ TestCallback receiveCallback();
+ TestCallback? receiveNullableCallback();
+ undefined passNullableTreatAsNullCallback(TestTreatAsNullCallback? arg);
+ undefined passOptionalNullableTreatAsNullCallback(optional TestTreatAsNullCallback? arg);
+ undefined passOptionalNullableTreatAsNullCallbackWithDefaultValue(optional TestTreatAsNullCallback? arg = null);
+ attribute TestTreatAsNullCallback treatAsNullCallback;
+ attribute TestTreatAsNullCallback? nullableTreatAsNullCallback;
+
+ // Force code generation of the various test callbacks we have.
+ undefined forceCallbackGeneration(TestIntegerReturn arg1,
+ TestNullableIntegerReturn arg2,
+ TestBooleanReturn arg3,
+ TestFloatReturn arg4,
+ TestStringReturn arg5,
+ TestEnumReturn arg6,
+ TestInterfaceReturn arg7,
+ TestNullableInterfaceReturn arg8,
+ TestExternalInterfaceReturn arg9,
+ TestNullableExternalInterfaceReturn arg10,
+ TestCallbackInterfaceReturn arg11,
+ TestNullableCallbackInterfaceReturn arg12,
+ TestCallbackReturn arg13,
+ TestNullableCallbackReturn arg14,
+ TestObjectReturn arg15,
+ TestNullableObjectReturn arg16,
+ TestTypedArrayReturn arg17,
+ TestNullableTypedArrayReturn arg18,
+ TestSequenceReturn arg19,
+ TestNullableSequenceReturn arg20,
+ TestIntegerArguments arg21,
+ TestInterfaceArguments arg22,
+ TestStringEnumArguments arg23,
+ TestObjectArguments arg24,
+ TestOptionalArguments arg25,
+ TestUnionArguments arg26,
+ TestUndefinedConstruction arg27,
+ TestIntegerConstruction arg28,
+ TestBooleanConstruction arg29,
+ TestFloatConstruction arg30,
+ TestStringConstruction arg31,
+ TestEnumConstruction arg32,
+ TestInterfaceConstruction arg33,
+ TestExternalInterfaceConstruction arg34,
+ TestCallbackInterfaceConstruction arg35,
+ TestCallbackConstruction arg36,
+ TestObjectConstruction arg37,
+ TestTypedArrayConstruction arg38,
+ TestSequenceConstruction arg39);
+
+ // Any types
+ undefined passAny(any arg);
+ undefined passVariadicAny(any... arg);
+ undefined passOptionalAny(optional any arg);
+ undefined passAnyDefaultNull(optional any arg = null);
+ undefined passSequenceOfAny(sequence<any> arg);
+ undefined passNullableSequenceOfAny(sequence<any>? arg);
+ undefined passOptionalSequenceOfAny(optional sequence<any> arg);
+ undefined passOptionalNullableSequenceOfAny(optional sequence<any>? arg);
+ undefined passOptionalSequenceOfAnyWithDefaultValue(optional sequence<any>? arg = null);
+ undefined passSequenceOfSequenceOfAny(sequence<sequence<any>> arg);
+ undefined passSequenceOfNullableSequenceOfAny(sequence<sequence<any>?> arg);
+ undefined passNullableSequenceOfNullableSequenceOfAny(sequence<sequence<any>?>? arg);
+ undefined passOptionalNullableSequenceOfNullableSequenceOfAny(optional sequence<sequence<any>?>? arg);
+ undefined passRecordOfAny(record<DOMString, any> arg);
+ undefined passNullableRecordOfAny(record<DOMString, any>? arg);
+ undefined passOptionalRecordOfAny(optional record<DOMString, any> arg);
+ undefined passOptionalNullableRecordOfAny(optional record<DOMString, any>? arg);
+ undefined passOptionalRecordOfAnyWithDefaultValue(optional record<DOMString, any>? arg = null);
+ undefined passRecordOfRecordOfAny(record<DOMString, record<DOMString, any>> arg);
+ undefined passRecordOfNullableRecordOfAny(record<DOMString, record<DOMString, any>?> arg);
+ undefined passNullableRecordOfNullableRecordOfAny(record<DOMString, record<DOMString, any>?>? arg);
+ undefined passOptionalNullableRecordOfNullableRecordOfAny(optional record<DOMString, record<DOMString, any>?>? arg);
+ undefined passOptionalNullableRecordOfNullableSequenceOfAny(optional record<DOMString, sequence<any>?>? arg);
+ undefined passOptionalNullableSequenceOfNullableRecordOfAny(optional sequence<record<DOMString, any>?>? arg);
+ any receiveAny();
+
+ // object types
+ undefined passObject(object arg);
+ undefined passVariadicObject(object... arg);
+ undefined passNullableObject(object? arg);
+ undefined passVariadicNullableObject(object... arg);
+ undefined passOptionalObject(optional object arg);
+ undefined passOptionalNullableObject(optional object? arg);
+ undefined passOptionalNullableObjectWithDefaultValue(optional object? arg = null);
+ undefined passSequenceOfObject(sequence<object> arg);
+ undefined passSequenceOfNullableObject(sequence<object?> arg);
+ undefined passNullableSequenceOfObject(sequence<object>? arg);
+ undefined passOptionalNullableSequenceOfNullableSequenceOfObject(optional sequence<sequence<object>?>? arg);
+ undefined passOptionalNullableSequenceOfNullableSequenceOfNullableObject(optional sequence<sequence<object?>?>? arg);
+ undefined passRecordOfObject(record<DOMString, object> arg);
+ object receiveObject();
+ object? receiveNullableObject();
+
+ // Union types
+ undefined passUnion((object or long) arg);
+ // Some union tests are debug-only to avoid creating all those
+ // unused union types in opt builds.
+#ifdef DEBUG
+ undefined passUnion2((long or boolean) arg);
+ undefined passUnion3((object or long or boolean) arg);
+ undefined passUnion4((Node or long or boolean) arg);
+ undefined passUnion5((object or boolean) arg);
+ undefined passUnion6((object or DOMString) arg);
+ undefined passUnion7((object or DOMString or long) arg);
+ undefined passUnion8((object or DOMString or boolean) arg);
+ undefined passUnion9((object or DOMString or long or boolean) arg);
+ undefined passUnion10(optional (EventInit or long) arg = {});
+ undefined passUnion11(optional (CustomEventInit or long) arg = {});
+ undefined passUnion12(optional (EventInit or long) arg = 5);
+ undefined passUnion13(optional (object or long?) arg = null);
+ undefined passUnion14(optional (object or long?) arg = 5);
+ undefined passUnion15((sequence<long> or long) arg);
+ undefined passUnion16(optional (sequence<long> or long) arg);
+ undefined passUnion17(optional (sequence<long>? or long) arg = 5);
+ undefined passUnion18((sequence<object> or long) arg);
+ undefined passUnion19(optional (sequence<object> or long) arg);
+ undefined passUnion20(optional (sequence<object> or long) arg = []);
+ undefined passUnion21((record<DOMString, long> or long) arg);
+ undefined passUnion22((record<DOMString, object> or long) arg);
+ undefined passUnion23((sequence<ImageData> or long) arg);
+ undefined passUnion24((sequence<ImageData?> or long) arg);
+ undefined passUnion25((sequence<sequence<ImageData>> or long) arg);
+ undefined passUnion26((sequence<sequence<ImageData?>> or long) arg);
+ undefined passUnion27(optional (sequence<DOMString> or EventInit) arg = {});
+ undefined passUnion28(optional (EventInit or sequence<DOMString>) arg = {});
+ undefined passUnionWithCallback((EventHandler or long) arg);
+ undefined passUnionWithByteString((ByteString or long) arg);
+ undefined passUnionWithUTF8String((UTF8String or long) arg);
+ undefined passUnionWithRecord((record<DOMString, DOMString> or DOMString) arg);
+ undefined passUnionWithRecordAndSequence((record<DOMString, DOMString> or sequence<DOMString>) arg);
+ undefined passUnionWithSequenceAndRecord((sequence<DOMString> or record<DOMString, DOMString>) arg);
+ undefined passUnionWithUSVS((USVString or long) arg);
+#endif
+ undefined passUnionWithNullable((object? or long) arg);
+ undefined passNullableUnion((object or long)? arg);
+ undefined passOptionalUnion(optional (object or long) arg);
+ undefined passOptionalNullableUnion(optional (object or long)? arg);
+ undefined passOptionalNullableUnionWithDefaultValue(optional (object or long)? arg = null);
+ //undefined passUnionWithInterfaces((TestInterface or TestExternalInterface) arg);
+ //undefined passUnionWithInterfacesAndNullable((TestInterface? or TestExternalInterface) arg);
+ //undefined passUnionWithSequence((sequence<object> or long) arg);
+ undefined passUnionWithArrayBuffer((UTF8String or ArrayBuffer) arg);
+ undefined passUnionWithArrayBufferOrNull((UTF8String or ArrayBuffer?) arg);
+ undefined passUnionWithTypedArrays((ArrayBufferView or ArrayBuffer) arg);
+ undefined passUnionWithTypedArraysOrNull((ArrayBufferView or ArrayBuffer?) arg);
+ undefined passUnionWithString((DOMString or object) arg);
+ // Using an enum in a union. Note that we use some enum not declared in our
+ // binding file, because UnionTypes.h will need to include the binding header
+ // for this enum. Pick an enum from an interface that won't drag in too much
+ // stuff.
+ undefined passUnionWithEnum((SupportedType or object) arg);
+
+ // Trying to use a callback in a union won't include the test
+ // headers, unfortunately, so won't compile.
+ //undefined passUnionWithCallback((TestCallback or long) arg);
+ undefined passUnionWithObject((object or long) arg);
+ //undefined passUnionWithDict((Dict or long) arg);
+
+ undefined passUnionWithDefaultValue1(optional (double or DOMString) arg = "");
+ undefined passUnionWithDefaultValue2(optional (double or DOMString) arg = 1);
+ undefined passUnionWithDefaultValue3(optional (double or DOMString) arg = 1.5);
+ undefined passUnionWithDefaultValue4(optional (float or DOMString) arg = "");
+ undefined passUnionWithDefaultValue5(optional (float or DOMString) arg = 1);
+ undefined passUnionWithDefaultValue6(optional (float or DOMString) arg = 1.5);
+ undefined passUnionWithDefaultValue7(optional (unrestricted double or DOMString) arg = "");
+ undefined passUnionWithDefaultValue8(optional (unrestricted double or DOMString) arg = 1);
+ undefined passUnionWithDefaultValue9(optional (unrestricted double or DOMString) arg = 1.5);
+ undefined passUnionWithDefaultValue10(optional (unrestricted double or DOMString) arg = Infinity);
+ undefined passUnionWithDefaultValue11(optional (unrestricted float or DOMString) arg = "");
+ undefined passUnionWithDefaultValue12(optional (unrestricted float or DOMString) arg = 1);
+ undefined passUnionWithDefaultValue13(optional (unrestricted float or DOMString) arg = Infinity);
+ undefined passUnionWithDefaultValue14(optional (double or ByteString) arg = "");
+ undefined passUnionWithDefaultValue15(optional (double or ByteString) arg = 1);
+ undefined passUnionWithDefaultValue16(optional (double or ByteString) arg = 1.5);
+ undefined passUnionWithDefaultValue17(optional (double or SupportedType) arg = "text/html");
+ undefined passUnionWithDefaultValue18(optional (double or SupportedType) arg = 1);
+ undefined passUnionWithDefaultValue19(optional (double or SupportedType) arg = 1.5);
+ undefined passUnionWithDefaultValue20(optional (double or USVString) arg = "abc");
+ undefined passUnionWithDefaultValue21(optional (double or USVString) arg = 1);
+ undefined passUnionWithDefaultValue22(optional (double or USVString) arg = 1.5);
+ undefined passUnionWithDefaultValue23(optional (double or UTF8String) arg = "");
+ undefined passUnionWithDefaultValue24(optional (double or UTF8String) arg = 1);
+ undefined passUnionWithDefaultValue25(optional (double or UTF8String) arg = 1.5);
+
+ undefined passNullableUnionWithDefaultValue1(optional (double or DOMString)? arg = "");
+ undefined passNullableUnionWithDefaultValue2(optional (double or DOMString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue3(optional (double or DOMString)? arg = null);
+ undefined passNullableUnionWithDefaultValue4(optional (float or DOMString)? arg = "");
+ undefined passNullableUnionWithDefaultValue5(optional (float or DOMString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue6(optional (float or DOMString)? arg = null);
+ undefined passNullableUnionWithDefaultValue7(optional (unrestricted double or DOMString)? arg = "");
+ undefined passNullableUnionWithDefaultValue8(optional (unrestricted double or DOMString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue9(optional (unrestricted double or DOMString)? arg = null);
+ undefined passNullableUnionWithDefaultValue10(optional (unrestricted float or DOMString)? arg = "");
+ undefined passNullableUnionWithDefaultValue11(optional (unrestricted float or DOMString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue12(optional (unrestricted float or DOMString)? arg = null);
+ undefined passNullableUnionWithDefaultValue13(optional (double or ByteString)? arg = "");
+ undefined passNullableUnionWithDefaultValue14(optional (double or ByteString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue15(optional (double or ByteString)? arg = 1.5);
+ undefined passNullableUnionWithDefaultValue16(optional (double or ByteString)? arg = null);
+ undefined passNullableUnionWithDefaultValue17(optional (double or SupportedType)? arg = "text/html");
+ undefined passNullableUnionWithDefaultValue18(optional (double or SupportedType)? arg = 1);
+ undefined passNullableUnionWithDefaultValue19(optional (double or SupportedType)? arg = 1.5);
+ undefined passNullableUnionWithDefaultValue20(optional (double or SupportedType)? arg = null);
+ undefined passNullableUnionWithDefaultValue21(optional (double or USVString)? arg = "abc");
+ undefined passNullableUnionWithDefaultValue22(optional (double or USVString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue23(optional (double or USVString)? arg = 1.5);
+ undefined passNullableUnionWithDefaultValue24(optional (double or USVString)? arg = null);
+
+ undefined passNullableUnionWithDefaultValue25(optional (double or UTF8String)? arg = "abc");
+ undefined passNullableUnionWithDefaultValue26(optional (double or UTF8String)? arg = 1);
+ undefined passNullableUnionWithDefaultValue27(optional (double or UTF8String)? arg = 1.5);
+ undefined passNullableUnionWithDefaultValue28(optional (double or UTF8String)? arg = null);
+
+ undefined passSequenceOfUnions(sequence<(CanvasPattern or CanvasGradient)> arg);
+ undefined passSequenceOfUnions2(sequence<(object or long)> arg);
+ undefined passVariadicUnion((CanvasPattern or CanvasGradient)... arg);
+
+ undefined passSequenceOfNullableUnions(sequence<(CanvasPattern or CanvasGradient)?> arg);
+ undefined passVariadicNullableUnion((CanvasPattern or CanvasGradient)?... arg);
+ undefined passRecordOfUnions(record<DOMString, (CanvasPattern or CanvasGradient)> arg);
+
+ // Each inner union in the following APIs should have a unique set
+ // of union member types, not used in any other API.
+ undefined passUnionWithSequenceOfUnions((DOMString or sequence<(OnlyForUseInInnerUnion or CanvasPattern)>) arg);
+ //undefined passUnionWithFrozenArrayOfUnions((DOMString or FrozenArray<(OnlyForUseInInnerUnion or CanvasGradient)>) arg);
+ undefined passUnionWithRecordOfUnions((sequence<long> or record<DOMString, (OnlyForUseInInnerUnion or sequence<long>)>) arg);
+
+ // XXXbz no move constructor on some unions
+ // undefined passRecordOfUnions2(record<DOMString, (object or long)> arg);
+
+ (CanvasPattern or CanvasGradient) receiveUnion();
+ (object or long) receiveUnion2();
+ (CanvasPattern? or CanvasGradient) receiveUnionContainingNull();
+ (CanvasPattern or CanvasGradient)? receiveNullableUnion();
+ (object or long)? receiveNullableUnion2();
+ (undefined or CanvasPattern) receiveUnionWithUndefined();
+ (undefined? or CanvasPattern) receiveUnionWithNullableUndefined();
+ (undefined or CanvasPattern?) receiveUnionWithUndefinedAndNullable();
+ (undefined or CanvasPattern)? receiveNullableUnionWithUndefined();
+
+ attribute (CanvasPattern or CanvasGradient) writableUnion;
+ attribute (CanvasPattern? or CanvasGradient) writableUnionContainingNull;
+ attribute (CanvasPattern or CanvasGradient)? writableNullableUnion;
+ attribute (undefined or CanvasPattern) writableUnionWithUndefined;
+ attribute (undefined? or CanvasPattern) writableUnionWithNullableUndefined;
+ attribute (undefined or CanvasPattern?) writableUnionWithUndefinedAndNullable;
+ attribute (undefined or CanvasPattern)? writableNullableUnionWithUndefined;
+
+ // Promise types
+ undefined passPromise(Promise<any> arg);
+ undefined passOptionalPromise(optional Promise<any> arg);
+ undefined passPromiseSequence(sequence<Promise<any>> arg);
+ Promise<any> receivePromise();
+ Promise<any> receiveAddrefedPromise();
+
+ // ObservableArray types
+ attribute ObservableArray<boolean> booleanObservableArray;
+ attribute ObservableArray<object> objectObservableArray;
+ attribute ObservableArray<any> anyObservableArray;
+ attribute ObservableArray<TestInterface> interfaceObservableArray;
+ attribute ObservableArray<long?> nullableObservableArray;
+
+ // binaryNames tests
+ [BinaryName="methodRenamedTo"]
+ undefined methodRenamedFrom();
+ [BinaryName="methodRenamedTo"]
+ undefined methodRenamedFrom(byte argument);
+ [BinaryName="attributeGetterRenamedTo"]
+ readonly attribute byte attributeGetterRenamedFrom;
+ [BinaryName="attributeRenamedTo"]
+ attribute byte attributeRenamedFrom;
+
+ undefined passDictionary(optional Dict x = {});
+ undefined passDictionary2(Dict x);
+ [Cached, Pure]
+ readonly attribute Dict readonlyDictionary;
+ [Cached, Pure]
+ readonly attribute Dict? readonlyNullableDictionary;
+ [Cached, Pure]
+ attribute Dict writableDictionary;
+ [Cached, Pure, Frozen]
+ readonly attribute Dict readonlyFrozenDictionary;
+ [Cached, Pure, Frozen]
+ readonly attribute Dict? readonlyFrozenNullableDictionary;
+ [Cached, Pure, Frozen]
+ attribute Dict writableFrozenDictionary;
+ Dict receiveDictionary();
+ Dict? receiveNullableDictionary();
+ undefined passOtherDictionary(optional GrandparentDict x = {});
+ undefined passSequenceOfDictionaries(sequence<Dict> x);
+ undefined passRecordOfDictionaries(record<DOMString, GrandparentDict> x);
+ // No support for nullable dictionaries inside a sequence (nor should there be)
+ // undefined passSequenceOfNullableDictionaries(sequence<Dict?> x);
+ undefined passDictionaryOrLong(optional Dict x = {});
+ undefined passDictionaryOrLong(long x);
+
+ undefined passDictContainingDict(optional DictContainingDict arg = {});
+ undefined passDictContainingSequence(optional DictContainingSequence arg = {});
+ DictContainingSequence receiveDictContainingSequence();
+ undefined passVariadicDictionary(Dict... arg);
+
+ // EnforceRange/Clamp tests
+ undefined dontEnforceRangeOrClamp(byte arg);
+ undefined doEnforceRange([EnforceRange] byte arg);
+ undefined doEnforceRangeNullable([EnforceRange] byte? arg);
+ undefined doClamp([Clamp] byte arg);
+ undefined doClampNullable([Clamp] byte? arg);
+ attribute [EnforceRange] byte enforcedByte;
+ attribute [EnforceRange] byte? enforcedNullableByte;
+ attribute [Clamp] byte clampedByte;
+ attribute [Clamp] byte? clampedNullableByte;
+
+ // Typedefs
+ const myLong myLongConstant = 5;
+ undefined exerciseTypedefInterfaces1(AnotherNameForTestInterface arg);
+ AnotherNameForTestInterface exerciseTypedefInterfaces2(NullableTestInterface arg);
+ undefined exerciseTypedefInterfaces3(YetAnotherNameForTestInterface arg);
+
+ // Deprecated methods and attributes
+ [Deprecated="Components"]
+ attribute byte deprecatedAttribute;
+ [Deprecated="Components"]
+ byte deprecatedMethod();
+ [Deprecated="Components"]
+ byte deprecatedMethodWithContext(any arg);
+
+ // Static methods and attributes
+ static attribute boolean staticAttribute;
+ static undefined staticMethod(boolean arg);
+ static undefined staticMethodWithContext(any arg);
+
+ // Testing static method with a reserved C++ keyword as the name
+ static undefined assert(boolean arg);
+
+ // Deprecated static methods and attributes
+ [Deprecated="Components"]
+ static attribute byte staticDeprecatedAttribute;
+ [Deprecated="Components"]
+ static undefined staticDeprecatedMethod();
+ [Deprecated="Components"]
+ static undefined staticDeprecatedMethodWithContext(any arg);
+
+ // Overload resolution tests
+ //undefined overload1(DOMString... strs);
+ boolean overload1(TestInterface arg);
+ TestInterface overload1(DOMString strs, TestInterface arg);
+ undefined overload2(TestInterface arg);
+ undefined overload2(optional Dict arg = {});
+ undefined overload2(boolean arg);
+ undefined overload2(DOMString arg);
+ undefined overload3(TestInterface arg);
+ undefined overload3(TestCallback arg);
+ undefined overload3(boolean arg);
+ undefined overload4(TestInterface arg);
+ undefined overload4(TestCallbackInterface arg);
+ undefined overload4(DOMString arg);
+ undefined overload5(long arg);
+ undefined overload5(TestEnum arg);
+ undefined overload6(long arg);
+ undefined overload6(boolean arg);
+ undefined overload7(long arg);
+ undefined overload7(boolean arg);
+ undefined overload7(ByteString arg);
+ undefined overload8(long arg);
+ undefined overload8(TestInterface arg);
+ undefined overload9(long? arg);
+ undefined overload9(DOMString arg);
+ undefined overload10(long? arg);
+ undefined overload10(object arg);
+ undefined overload11(long arg);
+ undefined overload11(DOMString? arg);
+ undefined overload12(long arg);
+ undefined overload12(boolean? arg);
+ undefined overload13(long? arg);
+ undefined overload13(boolean arg);
+ undefined overload14(optional long arg);
+ undefined overload14(TestInterface arg);
+ undefined overload15(long arg);
+ undefined overload15(optional TestInterface arg);
+ undefined overload16(long arg);
+ undefined overload16(optional TestInterface? arg);
+ undefined overload17(sequence<long> arg);
+ undefined overload17(record<DOMString, long> arg);
+ undefined overload18(record<DOMString, DOMString> arg);
+ undefined overload18(sequence<DOMString> arg);
+ undefined overload19(sequence<long> arg);
+ undefined overload19(optional Dict arg = {});
+ undefined overload20(optional Dict arg = {});
+ undefined overload20(sequence<long> arg);
+
+ // Variadic handling
+ undefined passVariadicThirdArg(DOMString arg1, long arg2, TestInterface... arg3);
+
+ // Conditionally exposed methods/attributes
+ [Pref="dom.webidl.test1"]
+ readonly attribute boolean prefable1;
+ [Pref="dom.webidl.test1"]
+ readonly attribute boolean prefable2;
+ [Pref="dom.webidl.test2"]
+ readonly attribute boolean prefable3;
+ [Pref="dom.webidl.test2"]
+ readonly attribute boolean prefable4;
+ [Pref="dom.webidl.test1"]
+ readonly attribute boolean prefable5;
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean prefable6;
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean prefable7;
+ [Pref="dom.webidl.test2", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean prefable8;
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean prefable9;
+ [Pref="dom.webidl.test1"]
+ undefined prefable10();
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ undefined prefable11();
+ [Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ readonly attribute boolean prefable12;
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ undefined prefable13();
+ [Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ readonly attribute boolean prefable14;
+ [Func="TestFuncControlledMember"]
+ readonly attribute boolean prefable15;
+ [Func="TestFuncControlledMember"]
+ readonly attribute boolean prefable16;
+ [Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ undefined prefable17();
+ [Func="TestFuncControlledMember"]
+ undefined prefable18();
+ [Func="TestFuncControlledMember"]
+ undefined prefable19();
+ [Pref="dom.webidl.test1", Func="TestFuncControlledMember", ChromeOnly]
+ undefined prefable20();
+ [Trial="TestTrial"]
+ undefined prefable21();
+ [Pref="dom.webidl.test1", Trial="TestTrial"]
+ undefined prefable22();
+
+ // Conditionally exposed methods/attributes involving [SecureContext]
+ [SecureContext]
+ readonly attribute boolean conditionalOnSecureContext1;
+ [SecureContext, Pref="dom.webidl.test1"]
+ readonly attribute boolean conditionalOnSecureContext2;
+ [SecureContext, Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean conditionalOnSecureContext3;
+ [SecureContext, Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ readonly attribute boolean conditionalOnSecureContext4;
+ [SecureContext]
+ undefined conditionalOnSecureContext5();
+ [SecureContext, Pref="dom.webidl.test1"]
+ undefined conditionalOnSecureContext6();
+ [SecureContext, Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ undefined conditionalOnSecureContext7();
+ [SecureContext, Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ undefined conditionalOnSecureContext8();
+ [SecureContext, Trial="TestTrial"]
+ readonly attribute boolean conditionalOnSecureContext9;
+ [SecureContext, Pref="dom.webidl.test1", Func="TestFuncControlledMember", Trial="TestTrial"]
+ undefined conditionalOnSecureContext10();
+
+ // Miscellania
+ [LegacyLenientThis] attribute long attrWithLenientThis;
+ [LegacyUnforgeable] readonly attribute long unforgeableAttr;
+ [LegacyUnforgeable, ChromeOnly] readonly attribute long unforgeableAttr2;
+ [LegacyUnforgeable] long unforgeableMethod();
+ [LegacyUnforgeable, ChromeOnly] long unforgeableMethod2();
+ stringifier;
+ undefined passRenamedInterface(TestRenamedInterface arg);
+ [PutForwards=writableByte] readonly attribute TestInterface putForwardsAttr;
+ [PutForwards=writableByte, LegacyLenientThis] readonly attribute TestInterface putForwardsAttr2;
+ [PutForwards=writableByte, ChromeOnly] readonly attribute TestInterface putForwardsAttr3;
+ [Throws] undefined throwingMethod();
+ [Throws] attribute boolean throwingAttr;
+ [GetterThrows] attribute boolean throwingGetterAttr;
+ [SetterThrows] attribute boolean throwingSetterAttr;
+ [CanOOM] undefined canOOMMethod();
+ [CanOOM] attribute boolean canOOMAttr;
+ [GetterCanOOM] attribute boolean canOOMGetterAttr;
+ [SetterCanOOM] attribute boolean canOOMSetterAttr;
+ [NeedsSubjectPrincipal] undefined needsSubjectPrincipalMethod();
+ [NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
+ [NeedsCallerType] undefined needsCallerTypeMethod();
+ [NeedsCallerType] attribute boolean needsCallerTypeAttr;
+ [NeedsSubjectPrincipal=NonSystem] undefined needsNonSystemSubjectPrincipalMethod();
+ [NeedsSubjectPrincipal=NonSystem] attribute boolean needsNonSystemSubjectPrincipalAttr;
+ [CEReactions] undefined ceReactionsMethod();
+ [CEReactions] undefined ceReactionsMethodOverload();
+ [CEReactions] undefined ceReactionsMethodOverload(DOMString bar);
+ [CEReactions] attribute boolean ceReactionsAttr;
+ legacycaller short(unsigned long arg1, TestInterface arg2);
+ undefined passArgsWithDefaults(optional long arg1,
+ optional TestInterface? arg2 = null,
+ optional Dict arg3 = {}, optional double arg4 = 5.0,
+ optional float arg5);
+
+ attribute any toJSONShouldSkipThis;
+ attribute TestParentInterface toJSONShouldSkipThis2;
+ attribute TestCallbackInterface toJSONShouldSkipThis3;
+ [Default] object toJSON();
+
+ attribute byte dashed-attribute;
+ undefined dashed-method();
+
+ // [NonEnumerable] tests
+ [NonEnumerable]
+ attribute boolean nonEnumerableAttr;
+ [NonEnumerable]
+ const boolean nonEnumerableConst = true;
+ [NonEnumerable]
+ undefined nonEnumerableMethod();
+
+ // [AllowShared] tests
+ attribute [AllowShared] ArrayBufferViewTypedef allowSharedArrayBufferViewTypedef;
+ attribute [AllowShared] ArrayBufferView allowSharedArrayBufferView;
+ attribute [AllowShared] ArrayBufferView? allowSharedNullableArrayBufferView;
+ attribute [AllowShared] ArrayBuffer allowSharedArrayBuffer;
+ attribute [AllowShared] ArrayBuffer? allowSharedNullableArrayBuffer;
+
+ undefined passAllowSharedArrayBufferViewTypedef(AllowSharedArrayBufferViewTypedef foo);
+ undefined passAllowSharedArrayBufferView([AllowShared] ArrayBufferView foo);
+ undefined passAllowSharedNullableArrayBufferView([AllowShared] ArrayBufferView? foo);
+ undefined passAllowSharedArrayBuffer([AllowShared] ArrayBuffer foo);
+ undefined passAllowSharedNullableArrayBuffer([AllowShared] ArrayBuffer? foo);
+ undefined passUnionArrayBuffer((DOMString or ArrayBuffer) foo);
+ undefined passUnionAllowSharedArrayBuffer((DOMString or [AllowShared] ArrayBuffer) foo);
+
+ // If you add things here, add them to TestExampleGen and TestJSImplGen as well
+};
+
+[Exposed=Window]
+interface TestParentInterface {
+};
+
+[Exposed=Window]
+interface TestChildInterface : TestParentInterface {
+};
+
+[Exposed=Window]
+interface TestNonWrapperCacheInterface {
+};
+
+interface mixin InterfaceMixin {
+ undefined mixedInMethod();
+ attribute boolean mixedInProperty;
+
+ const long mixedInConstant = 5;
+};
+
+dictionary Dict : ParentDict {
+ TestEnum someEnum;
+ long x;
+ long a;
+ long b = 8;
+ long z = 9;
+ [EnforceRange] unsigned long enforcedUnsignedLong;
+ [Clamp] unsigned long clampedUnsignedLong;
+ DOMString str;
+ DOMString empty = "";
+ TestEnum otherEnum = "b";
+ DOMString otherStr = "def";
+ DOMString? yetAnotherStr = null;
+ DOMString template;
+ ByteString byteStr;
+ ByteString emptyByteStr = "";
+ ByteString otherByteStr = "def";
+ // JSString jsStr; // NOT SUPPORTED YET
+ object someObj;
+ boolean prototype;
+ object? anotherObj = null;
+ TestCallback? someCallback = null;
+ any someAny;
+ any anotherAny = null;
+
+ unrestricted float urFloat = 0;
+ unrestricted float urFloat2 = 1.1;
+ unrestricted float urFloat3 = -1.1;
+ unrestricted float? urFloat4 = null;
+ unrestricted float infUrFloat = Infinity;
+ unrestricted float negativeInfUrFloat = -Infinity;
+ unrestricted float nanUrFloat = NaN;
+
+ unrestricted double urDouble = 0;
+ unrestricted double urDouble2 = 1.1;
+ unrestricted double urDouble3 = -1.1;
+ unrestricted double? urDouble4 = null;
+ unrestricted double infUrDouble = Infinity;
+ unrestricted double negativeInfUrDouble = -Infinity;
+ unrestricted double nanUrDouble = NaN;
+
+ (float or DOMString) floatOrString = "str";
+ (float or DOMString)? nullableFloatOrString = "str";
+ (object or long) objectOrLong;
+#ifdef DEBUG
+ (EventInit or long) eventInitOrLong;
+ (EventInit or long)? nullableEventInitOrLong;
+ (HTMLElement or long)? nullableHTMLElementOrLong;
+ // CustomEventInit is useful to test because it needs rooting.
+ (CustomEventInit or long) eventInitOrLong2;
+ (CustomEventInit or long)? nullableEventInitOrLong2;
+ (EventInit or long) eventInitOrLongWithDefaultValue = {};
+ (CustomEventInit or long) eventInitOrLongWithDefaultValue2 = {};
+ (EventInit or long) eventInitOrLongWithDefaultValue3 = 5;
+ (CustomEventInit or long) eventInitOrLongWithDefaultValue4 = 5;
+ (EventInit or long)? nullableEventInitOrLongWithDefaultValue = null;
+ (CustomEventInit or long)? nullableEventInitOrLongWithDefaultValue2 = null;
+ (EventInit or long)? nullableEventInitOrLongWithDefaultValue3 = 5;
+ (CustomEventInit or long)? nullableEventInitOrLongWithDefaultValue4 = 5;
+ (sequence<object> or long) objectSequenceOrLong;
+ (sequence<object> or long) objectSequenceOrLongWithDefaultValue1 = 1;
+ (sequence<object> or long) objectSequenceOrLongWithDefaultValue2 = [];
+ (sequence<object> or long)? nullableObjectSequenceOrLong;
+ (sequence<object> or long)? nullableObjectSequenceOrLongWithDefaultValue1 = 1;
+ (sequence<object> or long)? nullableObjectSequenceOrLongWithDefaultValue2 = [];
+#endif
+
+ ArrayBuffer arrayBuffer;
+ ArrayBuffer? nullableArrayBuffer;
+ Uint8Array uint8Array;
+ Float64Array? float64Array = null;
+
+ sequence<long> seq1;
+ sequence<long> seq2 = [];
+ sequence<long>? seq3;
+ sequence<long>? seq4 = null;
+ sequence<long>? seq5 = [];
+
+ long dashed-name;
+
+ required long requiredLong;
+ required object requiredObject;
+
+ CustomEventInit customEventInit;
+ TestDictionaryTypedef dictionaryTypedef;
+
+ Promise<undefined> promise;
+ sequence<Promise<undefined>> promiseSequence;
+
+ record<DOMString, long> recordMember;
+ record<DOMString, long>? nullableRecord;
+ record<DOMString, DOMString>? nullableRecordWithDefault = null;
+ record<USVString, long> usvStringRecord;
+ record<USVString, long>? nullableUSVStringRecordWithDefault = null;
+ record<ByteString, long> byteStringRecord;
+ record<ByteString, long>? nullableByteStringRecordWithDefault = null;
+ record<UTF8String, long> utf8StringRecord;
+ record<UTF8String, long>? nullableUTF8StringRecordWithDefault = null;
+ required record<DOMString, TestInterface> requiredRecord;
+ required record<USVString, TestInterface> requiredUSVRecord;
+ required record<ByteString, TestInterface> requiredByteRecord;
+ required record<UTF8String, TestInterface> requiredUTF8Record;
+};
+
+dictionary ParentDict : GrandparentDict {
+ long c = 5;
+ TestInterface someInterface;
+ TestInterface? someNullableInterface = null;
+ TestExternalInterface someExternalInterface;
+ any parentAny;
+};
+
+dictionary DictContainingDict {
+ Dict memberDict;
+};
+
+dictionary DictContainingSequence {
+ sequence<long> ourSequence;
+ sequence<TestInterface> ourSequence2;
+ sequence<any> ourSequence3;
+ sequence<object> ourSequence4;
+ sequence<object?> ourSequence5;
+ sequence<object>? ourSequence6;
+ sequence<object?>? ourSequence7;
+ sequence<object>? ourSequence8 = null;
+ sequence<object?>? ourSequence9 = null;
+ sequence<(float or DOMString)> ourSequence10;
+};
+
+dictionary DictForConstructor {
+ Dict dict;
+ DictContainingDict dict2;
+ sequence<Dict> seq1;
+ sequence<sequence<Dict>>? seq2;
+ sequence<sequence<Dict>?> seq3;
+ sequence<any> seq4;
+ sequence<any> seq5;
+ sequence<DictContainingSequence> seq6;
+ object obj1;
+ object? obj2;
+ any any1 = null;
+};
+
+dictionary DictWithConditionalMembers {
+ [ChromeOnly]
+ long chromeOnlyMember;
+ [Func="TestFuncControlledMember"]
+ long funcControlledMember;
+ [ChromeOnly, Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ long chromeOnlyFuncControlledMember;
+ // We need a pref name that's in StaticPrefList.h here.
+ [Pref="dom.webidl.test1"]
+ long prefControlledMember;
+ [Pref="dom.webidl.test1", ChromeOnly, Func="TestFuncControlledMember"]
+ long chromeOnlyFuncAndPrefControlledMember;
+};
+
+dictionary DictWithAllowSharedMembers {
+ [AllowShared] ArrayBufferView a;
+ [AllowShared] ArrayBufferView? b;
+ [AllowShared] ArrayBuffer c;
+ [AllowShared] ArrayBuffer? d;
+ [AllowShared] ArrayBufferViewTypedef e;
+ AllowSharedArrayBufferViewTypedef f;
+};
+
+dictionary DictWithBinaryType {
+ [BinaryType="nsAutoString"]
+ DOMString otherTypeOfStorageStr = "";
+};
+
+[Exposed=Window]
+interface TestIndexedGetterInterface {
+ getter long item(unsigned long idx);
+ readonly attribute unsigned long length;
+ legacycaller undefined();
+ [Cached, Pure] readonly attribute long cachedAttr;
+ [StoreInSlot, Pure] readonly attribute long storeInSlotAttr;
+};
+
+[Exposed=Window]
+interface TestNamedGetterInterface {
+ getter DOMString (DOMString name);
+};
+
+[Exposed=Window]
+interface TestIndexedGetterAndSetterAndNamedGetterInterface {
+ getter DOMString (DOMString myName);
+ getter long (unsigned long index);
+ setter undefined (unsigned long index, long arg);
+ readonly attribute unsigned long length;
+};
+
+[Exposed=Window]
+interface TestIndexedAndNamedGetterInterface {
+ getter long (unsigned long index);
+ getter DOMString namedItem(DOMString name);
+ readonly attribute unsigned long length;
+};
+
+[Exposed=Window]
+interface TestIndexedSetterInterface {
+ setter undefined setItem(unsigned long idx, DOMString item);
+ getter DOMString (unsigned long idx);
+ readonly attribute unsigned long length;
+};
+
+[Exposed=Window]
+interface TestNamedSetterInterface {
+ setter undefined (DOMString myName, TestIndexedSetterInterface item);
+ getter TestIndexedSetterInterface (DOMString name);
+};
+
+[Exposed=Window]
+interface TestIndexedAndNamedSetterInterface {
+ setter undefined (unsigned long index, TestIndexedSetterInterface item);
+ getter TestIndexedSetterInterface (unsigned long index);
+ readonly attribute unsigned long length;
+ setter undefined setNamedItem(DOMString name, TestIndexedSetterInterface item);
+ getter TestIndexedSetterInterface (DOMString name);
+};
+
+[Exposed=Window]
+interface TestIndexedAndNamedGetterAndSetterInterface : TestIndexedSetterInterface {
+ getter long item(unsigned long index);
+ getter DOMString namedItem(DOMString name);
+ setter undefined (unsigned long index, long item);
+ setter undefined (DOMString name, DOMString item);
+ stringifier DOMString ();
+ readonly attribute unsigned long length;
+};
+
+[Exposed=Window]
+interface TestNamedDeleterInterface {
+ deleter undefined (DOMString name);
+ getter long (DOMString name);
+};
+
+[Exposed=Window]
+interface TestNamedDeleterWithRetvalInterface {
+ deleter boolean delNamedItem(DOMString name);
+ getter long (DOMString name);
+};
+
+[Exposed=Window]
+interface TestCppKeywordNamedMethodsInterface {
+ boolean continue();
+ boolean delete();
+ long volatile();
+};
+
+[Deprecated="Components",
+ Exposed=Window]
+interface TestDeprecatedInterface {
+ constructor();
+
+ static undefined alsoDeprecated();
+};
+
+
+[Exposed=Window]
+interface TestInterfaceWithPromiseConstructorArg {
+ constructor(Promise<undefined> promise);
+};
+
+[Exposed=Window]
+namespace TestNamespace {
+ readonly attribute boolean foo;
+ long bar();
+};
+
+partial namespace TestNamespace {
+ undefined baz();
+};
+
+[ClassString="RenamedNamespaceClassName",
+ Exposed=Window]
+namespace TestRenamedNamespace {
+};
+
+[ProtoObjectHack,
+ Exposed=Window]
+namespace TestProtoObjectHackedNamespace {
+};
+
+[SecureContext,
+ Exposed=Window]
+interface TestSecureContextInterface {
+ static undefined alsoSecureContext();
+};
+
+[Exposed=(Window,Worker)]
+interface TestWorkerExposedInterface {
+ [NeedsSubjectPrincipal] undefined needsSubjectPrincipalMethod();
+ [NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
+ [NeedsCallerType] undefined needsCallerTypeMethod();
+ [NeedsCallerType] attribute boolean needsCallerTypeAttr;
+ [NeedsSubjectPrincipal=NonSystem] undefined needsNonSystemSubjectPrincipalMethod();
+ [NeedsSubjectPrincipal=NonSystem] attribute boolean needsNonSystemSubjectPrincipalAttr;
+};
+
+[Exposed=Window]
+interface TestHTMLConstructorInterface {
+ [HTMLConstructor] constructor();
+};
+
+[Exposed=Window]
+interface TestThrowingConstructorInterface {
+ [Throws]
+ constructor();
+ [Throws]
+ constructor(DOMString str);
+ [Throws]
+ constructor(unsigned long num, boolean? boolArg);
+ [Throws]
+ constructor(TestInterface? iface);
+ [Throws]
+ constructor(unsigned long arg1, TestInterface iface);
+ [Throws]
+ constructor(ArrayBuffer arrayBuf);
+ [Throws]
+ constructor(Uint8Array typedArr);
+ // [Throws] constructor(long arg1, long arg2, (TestInterface or OnlyForUseInConstructor) arg3);
+};
+
+[Exposed=Window]
+interface TestCEReactionsInterface {
+ [CEReactions] setter undefined (unsigned long index, long item);
+ [CEReactions] setter undefined (DOMString name, DOMString item);
+ [CEReactions] deleter undefined (DOMString name);
+ getter long item(unsigned long index);
+ getter DOMString (DOMString name);
+ readonly attribute unsigned long length;
+};
+
+typedef [EnforceRange] octet OctetRange;
+typedef [Clamp] octet OctetClamp;
+typedef [LegacyNullToEmptyString] DOMString NullEmptyString;
+// typedef [TreatNullAs=EmptyString] JSString NullEmptyJSString;
+
+dictionary TestAttributesOnDictionaryMembers {
+ [Clamp] octet a;
+ [ChromeOnly, Clamp] octet b;
+ required [Clamp] octet c;
+ [ChromeOnly] octet d;
+ // ChromeOnly doesn't mix with required, so we can't
+ // test [ChromeOnly] required [Clamp] octet e
+};
+
+[Exposed=Window]
+interface TestAttributesOnTypes {
+ undefined foo(OctetClamp thingy);
+ undefined bar(OctetRange thingy);
+ undefined baz(NullEmptyString thingy);
+ // undefined qux(NullEmptyJSString thingy);
+ attribute [Clamp] octet someAttr;
+ undefined argWithAttr([Clamp] octet arg0, optional [Clamp] octet arg1);
+ // There aren't any argument-only attributes that we can test here,
+ // TreatNonCallableAsNull isn't compatible with Clamp-able types
+};
+
+[Exposed=Window]
+interface TestPrefConstructorForInterface {
+ // Since only the constructor is under a pref,
+ // the generated constructor should check for the pref.
+ [Pref="dom.webidl.test1"] constructor();
+};
+
+[Exposed=Window, Pref="dom.webidl.test1"]
+interface TestConstructorForPrefInterface {
+ // Since the interface itself is under a Pref, there should be no
+ // check for the pref in the generated constructor.
+ constructor();
+};
+
+[Exposed=Window, Pref="dom.webidl.test1"]
+interface TestPrefConstructorForDifferentPrefInterface {
+ // Since the constructor's pref is different than the interface pref
+ // there should still be a check for the pref in the generated constructor.
+ [Pref="dom.webidl.test2"] constructor();
+};
+
+[Exposed=Window, SecureContext]
+interface TestConstructorForSCInterface {
+ // Since the interface itself is SecureContext, there should be no
+ // runtime check for SecureContext in the generated constructor.
+ constructor();
+};
+
+[Exposed=Window]
+interface TestSCConstructorForInterface {
+ // Since the interface context is unspecified but the constructor is
+ // SecureContext, the generated constructor should check for SecureContext.
+ [SecureContext] constructor();
+};
+
+[Exposed=Window, Func="IsNotUAWidget"]
+interface TestConstructorForFuncInterface {
+ // Since the interface has a Func attribute, but the constructor does not,
+ // the generated constructor should not check for the Func.
+ constructor();
+};
+
+[Exposed=Window]
+interface TestFuncConstructorForInterface {
+ // Since the constructor has a Func attribute, but the interface does not,
+ // the generated constructor should check for the Func.
+ [Func="IsNotUAWidget"]
+ constructor();
+};
+
+[Exposed=Window, Func="Document::AreWebAnimationsTimelinesEnabled"]
+interface TestFuncConstructorForDifferentFuncInterface {
+ // Since the constructor has a different Func attribute from the interface,
+ // the generated constructor should still check for its conditional func.
+ [Func="IsNotUAWidget"]
+ constructor();
+};
+
+[Exposed=Window]
+interface TestPrefChromeOnlySCFuncConstructorForInterface {
+ [Pref="dom.webidl.test1", ChromeOnly, SecureContext, Func="IsNotUAWidget"]
+ // There should be checks for all Pref/ChromeOnly/SecureContext/Func
+ // in the generated constructor.
+ constructor();
+};
diff --git a/dom/bindings/test/TestDictionary.webidl b/dom/bindings/test/TestDictionary.webidl
new file mode 100644
index 0000000000..37b7f5e84f
--- /dev/null
+++ b/dom/bindings/test/TestDictionary.webidl
@@ -0,0 +1,9 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+dictionary GrandparentDict {
+ double someNum;
+};
diff --git a/dom/bindings/test/TestExampleGen.webidl b/dom/bindings/test/TestExampleGen.webidl
new file mode 100644
index 0000000000..3d90e2bf9b
--- /dev/null
+++ b/dom/bindings/test/TestExampleGen.webidl
@@ -0,0 +1,914 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+[LegacyFactoryFunction=Example,
+ LegacyFactoryFunction=Example(DOMString str),
+ LegacyFactoryFunction=Example2(DictForConstructor dict, any any1, object obj1,
+ object? obj2, sequence<Dict> seq, optional any any2,
+ optional object obj3, optional object? obj4),
+ LegacyFactoryFunction=Example2((long or record<DOMString, any>) arg1),
+ Exposed=Window]
+interface TestExampleInterface {
+ constructor();
+ constructor(DOMString str);
+ constructor(unsigned long num, boolean? boolArg);
+ constructor(TestInterface? iface);
+ constructor(unsigned long arg1, TestInterface iface);
+ constructor(ArrayBuffer arrayBuf);
+ constructor(Uint8Array typedArr);
+ // constructor(long arg1, long arg2, (TestInterface or OnlyForUseInConstructor) arg3);
+
+ // Integer types
+ // XXXbz add tests for throwing versions of all the integer stuff
+ readonly attribute byte readonlyByte;
+ attribute byte writableByte;
+ undefined passByte(byte arg);
+ byte receiveByte();
+ undefined passOptionalByte(optional byte arg);
+ undefined passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
+ undefined passOptionalByteWithDefault(optional byte arg = 0);
+ undefined passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
+ undefined passNullableByte(byte? arg);
+ undefined passOptionalNullableByte(optional byte? arg);
+ undefined passVariadicByte(byte... arg);
+ [Cached, Pure]
+ readonly attribute byte cachedByte;
+ [StoreInSlot, Constant]
+ readonly attribute byte cachedConstantByte;
+ [Cached, Pure]
+ attribute byte cachedWritableByte;
+ [Affects=Nothing]
+ attribute byte sideEffectFreeByte;
+ [Affects=Nothing, DependsOn=DOMState]
+ attribute byte domDependentByte;
+ [Affects=Nothing, DependsOn=Nothing]
+ readonly attribute byte constantByte;
+ [DependsOn=DeviceState, Affects=Nothing]
+ readonly attribute byte deviceStateDependentByte;
+ [Affects=Nothing]
+ byte returnByteSideEffectFree();
+ [Affects=Nothing, DependsOn=DOMState]
+ byte returnDOMDependentByte();
+ [Affects=Nothing, DependsOn=Nothing]
+ byte returnConstantByte();
+ [DependsOn=DeviceState, Affects=Nothing]
+ byte returnDeviceStateDependentByte();
+
+ readonly attribute short readonlyShort;
+ attribute short writableShort;
+ undefined passShort(short arg);
+ short receiveShort();
+ undefined passOptionalShort(optional short arg);
+ undefined passOptionalShortWithDefault(optional short arg = 5);
+
+ readonly attribute long readonlyLong;
+ attribute long writableLong;
+ undefined passLong(long arg);
+ long receiveLong();
+ undefined passOptionalLong(optional long arg);
+ undefined passOptionalLongWithDefault(optional long arg = 7);
+
+ readonly attribute long long readonlyLongLong;
+ attribute long long writableLongLong;
+ undefined passLongLong(long long arg);
+ long long receiveLongLong();
+ undefined passOptionalLongLong(optional long long arg);
+ undefined passOptionalLongLongWithDefault(optional long long arg = -12);
+
+ readonly attribute octet readonlyOctet;
+ attribute octet writableOctet;
+ undefined passOctet(octet arg);
+ octet receiveOctet();
+ undefined passOptionalOctet(optional octet arg);
+ undefined passOptionalOctetWithDefault(optional octet arg = 19);
+
+ readonly attribute unsigned short readonlyUnsignedShort;
+ attribute unsigned short writableUnsignedShort;
+ undefined passUnsignedShort(unsigned short arg);
+ unsigned short receiveUnsignedShort();
+ undefined passOptionalUnsignedShort(optional unsigned short arg);
+ undefined passOptionalUnsignedShortWithDefault(optional unsigned short arg = 2);
+
+ readonly attribute unsigned long readonlyUnsignedLong;
+ attribute unsigned long writableUnsignedLong;
+ undefined passUnsignedLong(unsigned long arg);
+ unsigned long receiveUnsignedLong();
+ undefined passOptionalUnsignedLong(optional unsigned long arg);
+ undefined passOptionalUnsignedLongWithDefault(optional unsigned long arg = 6);
+
+ readonly attribute unsigned long long readonlyUnsignedLongLong;
+ attribute unsigned long long writableUnsignedLongLong;
+ undefined passUnsignedLongLong(unsigned long long arg);
+ unsigned long long receiveUnsignedLongLong();
+ undefined passOptionalUnsignedLongLong(optional unsigned long long arg);
+ undefined passOptionalUnsignedLongLongWithDefault(optional unsigned long long arg = 17);
+
+ attribute float writableFloat;
+ attribute unrestricted float writableUnrestrictedFloat;
+ attribute float? writableNullableFloat;
+ attribute unrestricted float? writableNullableUnrestrictedFloat;
+ attribute double writableDouble;
+ attribute unrestricted double writableUnrestrictedDouble;
+ attribute double? writableNullableDouble;
+ attribute unrestricted double? writableNullableUnrestrictedDouble;
+ undefined passFloat(float arg1, unrestricted float arg2,
+ float? arg3, unrestricted float? arg4,
+ double arg5, unrestricted double arg6,
+ double? arg7, unrestricted double? arg8,
+ sequence<float> arg9, sequence<unrestricted float> arg10,
+ sequence<float?> arg11, sequence<unrestricted float?> arg12,
+ sequence<double> arg13, sequence<unrestricted double> arg14,
+ sequence<double?> arg15, sequence<unrestricted double?> arg16);
+ [LenientFloat]
+ undefined passLenientFloat(float arg1, unrestricted float arg2,
+ float? arg3, unrestricted float? arg4,
+ double arg5, unrestricted double arg6,
+ double? arg7, unrestricted double? arg8,
+ sequence<float> arg9,
+ sequence<unrestricted float> arg10,
+ sequence<float?> arg11,
+ sequence<unrestricted float?> arg12,
+ sequence<double> arg13,
+ sequence<unrestricted double> arg14,
+ sequence<double?> arg15,
+ sequence<unrestricted double?> arg16);
+ [LenientFloat]
+ attribute float lenientFloatAttr;
+ [LenientFloat]
+ attribute double lenientDoubleAttr;
+
+ // Castable interface types
+ // XXXbz add tests for throwing versions of all the castable interface stuff
+ TestInterface receiveSelf();
+ TestInterface? receiveNullableSelf();
+ TestInterface receiveWeakSelf();
+ TestInterface? receiveWeakNullableSelf();
+ undefined passSelf(TestInterface arg);
+ undefined passNullableSelf(TestInterface? arg);
+ attribute TestInterface nonNullSelf;
+ attribute TestInterface? nullableSelf;
+ [Cached, Pure]
+ readonly attribute TestInterface cachedSelf;
+ // Optional arguments
+ undefined passOptionalSelf(optional TestInterface? arg);
+ undefined passOptionalNonNullSelf(optional TestInterface arg);
+ undefined passOptionalSelfWithDefault(optional TestInterface? arg = null);
+
+ // Non-wrapper-cache interface types
+ [NewObject]
+ TestNonWrapperCacheInterface receiveNonWrapperCacheInterface();
+ [NewObject]
+ TestNonWrapperCacheInterface? receiveNullableNonWrapperCacheInterface();
+ [NewObject]
+ sequence<TestNonWrapperCacheInterface> receiveNonWrapperCacheInterfaceSequence();
+ [NewObject]
+ sequence<TestNonWrapperCacheInterface?> receiveNullableNonWrapperCacheInterfaceSequence();
+ [NewObject]
+ sequence<TestNonWrapperCacheInterface>? receiveNonWrapperCacheInterfaceNullableSequence();
+ [NewObject]
+ sequence<TestNonWrapperCacheInterface?>? receiveNullableNonWrapperCacheInterfaceNullableSequence();
+
+ // External interface types
+ TestExternalInterface receiveExternal();
+ TestExternalInterface? receiveNullableExternal();
+ TestExternalInterface receiveWeakExternal();
+ TestExternalInterface? receiveWeakNullableExternal();
+ undefined passExternal(TestExternalInterface arg);
+ undefined passNullableExternal(TestExternalInterface? arg);
+ attribute TestExternalInterface nonNullExternal;
+ attribute TestExternalInterface? nullableExternal;
+ // Optional arguments
+ undefined passOptionalExternal(optional TestExternalInterface? arg);
+ undefined passOptionalNonNullExternal(optional TestExternalInterface arg);
+ undefined passOptionalExternalWithDefault(optional TestExternalInterface? arg = null);
+
+ // Callback interface types
+ TestCallbackInterface receiveCallbackInterface();
+ TestCallbackInterface? receiveNullableCallbackInterface();
+ TestCallbackInterface receiveWeakCallbackInterface();
+ TestCallbackInterface? receiveWeakNullableCallbackInterface();
+ undefined passCallbackInterface(TestCallbackInterface arg);
+ undefined passNullableCallbackInterface(TestCallbackInterface? arg);
+ attribute TestCallbackInterface nonNullCallbackInterface;
+ attribute TestCallbackInterface? nullableCallbackInterface;
+ // Optional arguments
+ undefined passOptionalCallbackInterface(optional TestCallbackInterface? arg);
+ undefined passOptionalNonNullCallbackInterface(optional TestCallbackInterface arg);
+ undefined passOptionalCallbackInterfaceWithDefault(optional TestCallbackInterface? arg = null);
+
+ // Sequence types
+ [Cached, Pure]
+ readonly attribute sequence<long> readonlySequence;
+ [Cached, Pure]
+ readonly attribute sequence<Dict> readonlySequenceOfDictionaries;
+ [Cached, Pure]
+ readonly attribute sequence<Dict>? readonlyNullableSequenceOfDictionaries;
+ [Cached, Pure, Frozen]
+ readonly attribute sequence<long> readonlyFrozenSequence;
+ [Cached, Pure, Frozen]
+ readonly attribute sequence<long>? readonlyFrozenNullableSequence;
+ sequence<long> receiveSequence();
+ sequence<long>? receiveNullableSequence();
+ sequence<long?> receiveSequenceOfNullableInts();
+ sequence<long?>? receiveNullableSequenceOfNullableInts();
+ undefined passSequence(sequence<long> arg);
+ undefined passNullableSequence(sequence<long>? arg);
+ undefined passSequenceOfNullableInts(sequence<long?> arg);
+ undefined passOptionalSequenceOfNullableInts(optional sequence<long?> arg);
+ undefined passOptionalNullableSequenceOfNullableInts(optional sequence<long?>? arg);
+ sequence<TestInterface> receiveCastableObjectSequence();
+ sequence<TestCallbackInterface> receiveCallbackObjectSequence();
+ sequence<TestInterface?> receiveNullableCastableObjectSequence();
+ sequence<TestCallbackInterface?> receiveNullableCallbackObjectSequence();
+ sequence<TestInterface>? receiveCastableObjectNullableSequence();
+ sequence<TestInterface?>? receiveNullableCastableObjectNullableSequence();
+ sequence<TestInterface> receiveWeakCastableObjectSequence();
+ sequence<TestInterface?> receiveWeakNullableCastableObjectSequence();
+ sequence<TestInterface>? receiveWeakCastableObjectNullableSequence();
+ sequence<TestInterface?>? receiveWeakNullableCastableObjectNullableSequence();
+ undefined passCastableObjectSequence(sequence<TestInterface> arg);
+ undefined passNullableCastableObjectSequence(sequence<TestInterface?> arg);
+ undefined passCastableObjectNullableSequence(sequence<TestInterface>? arg);
+ undefined passNullableCastableObjectNullableSequence(sequence<TestInterface?>? arg);
+ undefined passOptionalSequence(optional sequence<long> arg);
+ undefined passOptionalSequenceWithDefaultValue(optional sequence<long> arg = []);
+ undefined passOptionalNullableSequence(optional sequence<long>? arg);
+ undefined passOptionalNullableSequenceWithDefaultValue(optional sequence<long>? arg = null);
+ undefined passOptionalNullableSequenceWithDefaultValue2(optional sequence<long>? arg = []);
+ undefined passOptionalObjectSequence(optional sequence<TestInterface> arg);
+ undefined passExternalInterfaceSequence(sequence<TestExternalInterface> arg);
+ undefined passNullableExternalInterfaceSequence(sequence<TestExternalInterface?> arg);
+
+ sequence<DOMString> receiveStringSequence();
+ undefined passStringSequence(sequence<DOMString> arg);
+
+ sequence<ByteString> receiveByteStringSequence();
+ undefined passByteStringSequence(sequence<ByteString> arg);
+
+ sequence<UTF8String> receiveUTF8StringSequence();
+ undefined passUTF8StringSequence(sequence<UTF8String> arg);
+
+ sequence<any> receiveAnySequence();
+ sequence<any>? receiveNullableAnySequence();
+ //XXXbz No support for sequence of sequence return values yet.
+ //sequence<sequence<any>> receiveAnySequenceSequence();
+
+ sequence<object> receiveObjectSequence();
+ sequence<object?> receiveNullableObjectSequence();
+
+ undefined passSequenceOfSequences(sequence<sequence<long>> arg);
+ undefined passSequenceOfSequencesOfSequences(sequence<sequence<sequence<long>>> arg);
+ //XXXbz No support for sequence of sequence return values yet.
+ //sequence<sequence<long>> receiveSequenceOfSequences();
+
+ // record types
+ undefined passRecord(record<DOMString, long> arg);
+ undefined passNullableRecord(record<DOMString, long>? arg);
+ undefined passRecordOfNullableInts(record<DOMString, long?> arg);
+ undefined passOptionalRecordOfNullableInts(optional record<DOMString, long?> arg);
+ undefined passOptionalNullableRecordOfNullableInts(optional record<DOMString, long?>? arg);
+ undefined passCastableObjectRecord(record<DOMString, TestInterface> arg);
+ undefined passNullableCastableObjectRecord(record<DOMString, TestInterface?> arg);
+ undefined passCastableObjectNullableRecord(record<DOMString, TestInterface>? arg);
+ undefined passNullableCastableObjectNullableRecord(record<DOMString, TestInterface?>? arg);
+ undefined passOptionalRecord(optional record<DOMString, long> arg);
+ undefined passOptionalNullableRecord(optional record<DOMString, long>? arg);
+ undefined passOptionalNullableRecordWithDefaultValue(optional record<DOMString, long>? arg = null);
+ undefined passOptionalObjectRecord(optional record<DOMString, TestInterface> arg);
+ undefined passExternalInterfaceRecord(record<DOMString, TestExternalInterface> arg);
+ undefined passNullableExternalInterfaceRecord(record<DOMString, TestExternalInterface?> arg);
+ undefined passStringRecord(record<DOMString, DOMString> arg);
+ undefined passByteStringRecord(record<DOMString, ByteString> arg);
+ undefined passUTF8StringRecord(record<DOMString, UTF8String> arg);
+ undefined passRecordOfRecords(record<DOMString, record<DOMString, long>> arg);
+ record<DOMString, long> receiveRecord();
+ record<DOMString, long>? receiveNullableRecord();
+ record<DOMString, long?> receiveRecordOfNullableInts();
+ record<DOMString, long?>? receiveNullableRecordOfNullableInts();
+ //XXXbz No support for record of records return values yet.
+ //record<DOMString, record<DOMString, long>> receiveRecordOfRecords();
+ record<DOMString, any> receiveAnyRecord();
+
+ // Typed array types
+ undefined passArrayBuffer(ArrayBuffer arg);
+ undefined passNullableArrayBuffer(ArrayBuffer? arg);
+ undefined passOptionalArrayBuffer(optional ArrayBuffer arg);
+ undefined passOptionalNullableArrayBuffer(optional ArrayBuffer? arg);
+ undefined passOptionalNullableArrayBufferWithDefaultValue(optional ArrayBuffer? arg= null);
+ undefined passArrayBufferView(ArrayBufferView arg);
+ undefined passInt8Array(Int8Array arg);
+ undefined passInt16Array(Int16Array arg);
+ undefined passInt32Array(Int32Array arg);
+ undefined passUint8Array(Uint8Array arg);
+ undefined passUint16Array(Uint16Array arg);
+ undefined passUint32Array(Uint32Array arg);
+ undefined passUint8ClampedArray(Uint8ClampedArray arg);
+ undefined passFloat32Array(Float32Array arg);
+ undefined passFloat64Array(Float64Array arg);
+ undefined passSequenceOfArrayBuffers(sequence<ArrayBuffer> arg);
+ undefined passSequenceOfNullableArrayBuffers(sequence<ArrayBuffer?> arg);
+ undefined passRecordOfArrayBuffers(record<DOMString, ArrayBuffer> arg);
+ undefined passRecordOfNullableArrayBuffers(record<DOMString, ArrayBuffer?> arg);
+ undefined passVariadicTypedArray(Float32Array... arg);
+ undefined passVariadicNullableTypedArray(Float32Array?... arg);
+ Uint8Array receiveUint8Array();
+ attribute Uint8Array uint8ArrayAttr;
+
+ // DOMString types
+ undefined passString(DOMString arg);
+ undefined passNullableString(DOMString? arg);
+ undefined passOptionalString(optional DOMString arg);
+ undefined passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
+ undefined passOptionalNullableString(optional DOMString? arg);
+ undefined passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
+ undefined passVariadicString(DOMString... arg);
+
+ // ByteString types
+ undefined passByteString(ByteString arg);
+ undefined passNullableByteString(ByteString? arg);
+ undefined passOptionalByteString(optional ByteString arg);
+ undefined passOptionalByteStringWithDefaultValue(optional ByteString arg = "abc");
+ undefined passOptionalNullableByteString(optional ByteString? arg);
+ undefined passOptionalNullableByteStringWithDefaultValue(optional ByteString? arg = null);
+ undefined passVariadicByteString(ByteString... arg);
+ undefined passUnionByteString((ByteString or long) arg);
+ undefined passOptionalUnionByteString(optional (ByteString or long) arg);
+ undefined passOptionalUnionByteStringWithDefaultValue(optional (ByteString or long) arg = "abc");
+
+ // UTF8String types
+ undefined passUTF8String(UTF8String arg);
+ undefined passNullableUTF8String(UTF8String? arg);
+ undefined passOptionalUTF8String(optional UTF8String arg);
+ undefined passOptionalUTF8StringWithDefaultValue(optional UTF8String arg = "abc");
+ undefined passOptionalNullableUTF8String(optional UTF8String? arg);
+ undefined passOptionalNullableUTF8StringWithDefaultValue(optional UTF8String? arg = null);
+ undefined passVariadicUTF8String(UTF8String... arg);
+ undefined passUnionUTF8String((UTF8String or long) arg);
+ undefined passOptionalUnionUTF8String(optional (UTF8String or long) arg);
+ undefined passOptionalUnionUTF8StringWithDefaultValue(optional (UTF8String or long) arg = "abc");
+
+ // USVString types
+ undefined passSVS(USVString arg);
+ undefined passNullableSVS(USVString? arg);
+ undefined passOptionalSVS(optional USVString arg);
+ undefined passOptionalSVSWithDefaultValue(optional USVString arg = "abc");
+ undefined passOptionalNullableSVS(optional USVString? arg);
+ undefined passOptionalNullableSVSWithDefaultValue(optional USVString? arg = null);
+ undefined passVariadicSVS(USVString... arg);
+ USVString receiveSVS();
+
+ // JSString types
+ undefined passJSString(JSString arg);
+ // undefined passNullableJSString(JSString? arg); // NOT SUPPORTED YET
+ // undefined passOptionalJSString(optional JSString arg); // NOT SUPPORTED YET
+ undefined passOptionalJSStringWithDefaultValue(optional JSString arg = "abc");
+ // undefined passOptionalNullableJSString(optional JSString? arg); // NOT SUPPORTED YET
+ // undefined passOptionalNullableJSStringWithDefaultValue(optional JSString? arg = null); // NOT SUPPORTED YET
+ // undefined passVariadicJSString(JSString... arg); // NOT SUPPORTED YET
+ // undefined passRecordOfJSString(record<DOMString, JSString> arg); // NOT SUPPORTED YET
+ // undefined passSequenceOfJSString(sequence<JSString> arg); // NOT SUPPORTED YET
+ // undefined passUnionJSString((JSString or long) arg); // NOT SUPPORTED YET
+ JSString receiveJSString();
+ // sequence<JSString> receiveJSStringSequence(); // NOT SUPPORTED YET
+ // (JSString or long) receiveJSStringUnion(); // NOT SUPPORTED YET
+ // record<DOMString, JSString> receiveJSStringRecord(); // NOT SUPPORTED YET
+ readonly attribute JSString readonlyJSStringAttr;
+ attribute JSString jsStringAttr;
+
+ // Enumerated types
+ undefined passEnum(TestEnum arg);
+ undefined passNullableEnum(TestEnum? arg);
+ undefined passOptionalEnum(optional TestEnum arg);
+ undefined passEnumWithDefault(optional TestEnum arg = "a");
+ undefined passOptionalNullableEnum(optional TestEnum? arg);
+ undefined passOptionalNullableEnumWithDefaultValue(optional TestEnum? arg = null);
+ undefined passOptionalNullableEnumWithDefaultValue2(optional TestEnum? arg = "a");
+ TestEnum receiveEnum();
+ TestEnum? receiveNullableEnum();
+ attribute TestEnum enumAttribute;
+ readonly attribute TestEnum readonlyEnumAttribute;
+
+ // Callback types
+ undefined passCallback(TestCallback arg);
+ undefined passNullableCallback(TestCallback? arg);
+ undefined passOptionalCallback(optional TestCallback arg);
+ undefined passOptionalNullableCallback(optional TestCallback? arg);
+ undefined passOptionalNullableCallbackWithDefaultValue(optional TestCallback? arg = null);
+ TestCallback receiveCallback();
+ TestCallback? receiveNullableCallback();
+ undefined passNullableTreatAsNullCallback(TestTreatAsNullCallback? arg);
+ undefined passOptionalNullableTreatAsNullCallback(optional TestTreatAsNullCallback? arg);
+ undefined passOptionalNullableTreatAsNullCallbackWithDefaultValue(optional TestTreatAsNullCallback? arg = null);
+
+ // Any types
+ undefined passAny(any arg);
+ undefined passVariadicAny(any... arg);
+ undefined passOptionalAny(optional any arg);
+ undefined passAnyDefaultNull(optional any arg = null);
+ undefined passSequenceOfAny(sequence<any> arg);
+ undefined passNullableSequenceOfAny(sequence<any>? arg);
+ undefined passOptionalSequenceOfAny(optional sequence<any> arg);
+ undefined passOptionalNullableSequenceOfAny(optional sequence<any>? arg);
+ undefined passOptionalSequenceOfAnyWithDefaultValue(optional sequence<any>? arg = null);
+ undefined passSequenceOfSequenceOfAny(sequence<sequence<any>> arg);
+ undefined passSequenceOfNullableSequenceOfAny(sequence<sequence<any>?> arg);
+ undefined passNullableSequenceOfNullableSequenceOfAny(sequence<sequence<any>?>? arg);
+ undefined passOptionalNullableSequenceOfNullableSequenceOfAny(optional sequence<sequence<any>?>? arg);
+ undefined passRecordOfAny(record<DOMString, any> arg);
+ undefined passNullableRecordOfAny(record<DOMString, any>? arg);
+ undefined passOptionalRecordOfAny(optional record<DOMString, any> arg);
+ undefined passOptionalNullableRecordOfAny(optional record<DOMString, any>? arg);
+ undefined passOptionalRecordOfAnyWithDefaultValue(optional record<DOMString, any>? arg = null);
+ undefined passRecordOfRecordOfAny(record<DOMString, record<DOMString, any>> arg);
+ undefined passRecordOfNullableRecordOfAny(record<DOMString, record<DOMString, any>?> arg);
+ undefined passNullableRecordOfNullableRecordOfAny(record<DOMString, record<DOMString, any>?>? arg);
+ undefined passOptionalNullableRecordOfNullableRecordOfAny(optional record<DOMString, record<DOMString, any>?>? arg);
+ undefined passOptionalNullableRecordOfNullableSequenceOfAny(optional record<DOMString, sequence<any>?>? arg);
+ undefined passOptionalNullableSequenceOfNullableRecordOfAny(optional sequence<record<DOMString, any>?>? arg);
+ any receiveAny();
+
+ // object types
+ undefined passObject(object arg);
+ undefined passVariadicObject(object... arg);
+ undefined passNullableObject(object? arg);
+ undefined passVariadicNullableObject(object... arg);
+ undefined passOptionalObject(optional object arg);
+ undefined passOptionalNullableObject(optional object? arg);
+ undefined passOptionalNullableObjectWithDefaultValue(optional object? arg = null);
+ undefined passSequenceOfObject(sequence<object> arg);
+ undefined passSequenceOfNullableObject(sequence<object?> arg);
+ undefined passNullableSequenceOfObject(sequence<object>? arg);
+ undefined passOptionalNullableSequenceOfNullableSequenceOfObject(optional sequence<sequence<object>?>? arg);
+ undefined passOptionalNullableSequenceOfNullableSequenceOfNullableObject(optional sequence<sequence<object?>?>? arg);
+ undefined passRecordOfObject(record<DOMString, object> arg);
+ object receiveObject();
+ object? receiveNullableObject();
+
+ // Union types
+ undefined passUnion((object or long) arg);
+ // Some union tests are debug-only to avoid creating all those
+ // unused union types in opt builds.
+
+#ifdef DEBUG
+ undefined passUnion2((long or boolean) arg);
+ undefined passUnion3((object or long or boolean) arg);
+ undefined passUnion4((Node or long or boolean) arg);
+ undefined passUnion5((object or boolean) arg);
+ undefined passUnion6((object or DOMString) arg);
+ undefined passUnion7((object or DOMString or long) arg);
+ undefined passUnion8((object or DOMString or boolean) arg);
+ undefined passUnion9((object or DOMString or long or boolean) arg);
+ undefined passUnion10(optional (EventInit or long) arg = {});
+ undefined passUnion11(optional (CustomEventInit or long) arg = {});
+ undefined passUnion12(optional (EventInit or long) arg = 5);
+ undefined passUnion13(optional (object or long?) arg = null);
+ undefined passUnion14(optional (object or long?) arg = 5);
+ undefined passUnion15((sequence<long> or long) arg);
+ undefined passUnion16(optional (sequence<long> or long) arg);
+ undefined passUnion17(optional (sequence<long>? or long) arg = 5);
+ undefined passUnion18((sequence<object> or long) arg);
+ undefined passUnion19(optional (sequence<object> or long) arg);
+ undefined passUnion20(optional (sequence<object> or long) arg = []);
+ undefined passUnion21((record<DOMString, long> or long) arg);
+ undefined passUnion22((record<DOMString, object> or long) arg);
+ undefined passUnion23((sequence<ImageData> or long) arg);
+ undefined passUnion24((sequence<ImageData?> or long) arg);
+ undefined passUnion25((sequence<sequence<ImageData>> or long) arg);
+ undefined passUnion26((sequence<sequence<ImageData?>> or long) arg);
+ undefined passUnion27(optional (sequence<DOMString> or EventInit) arg = {});
+ undefined passUnion28(optional (EventInit or sequence<DOMString>) arg = {});
+ undefined passUnionWithCallback((EventHandler or long) arg);
+ undefined passUnionWithByteString((ByteString or long) arg);
+ undefined passUnionWithUTF8String((UTF8String or long) arg);
+ undefined passUnionWithRecord((record<DOMString, DOMString> or DOMString) arg);
+ undefined passUnionWithRecordAndSequence((record<DOMString, DOMString> or sequence<DOMString>) arg);
+ undefined passUnionWithSequenceAndRecord((sequence<DOMString> or record<DOMString, DOMString>) arg);
+ undefined passUnionWithSVS((USVString or long) arg);
+#endif
+ undefined passUnionWithNullable((object? or long) arg);
+ undefined passNullableUnion((object or long)? arg);
+ undefined passOptionalUnion(optional (object or long) arg);
+ undefined passOptionalNullableUnion(optional (object or long)? arg);
+ undefined passOptionalNullableUnionWithDefaultValue(optional (object or long)? arg = null);
+ //undefined passUnionWithInterfaces((TestInterface or TestExternalInterface) arg);
+ //undefined passUnionWithInterfacesAndNullable((TestInterface? or TestExternalInterface) arg);
+ //undefined passUnionWithSequence((sequence<object> or long) arg);
+ undefined passUnionWithArrayBuffer((UTF8String or ArrayBuffer) arg);
+ undefined passUnionWithArrayBufferOrNull((UTF8String or ArrayBuffer?) arg);
+ undefined passUnionWithTypedArrays((ArrayBufferView or ArrayBuffer) arg);
+ undefined passUnionWithTypedArraysOrNull((ArrayBufferView or ArrayBuffer?) arg);
+ undefined passUnionWithString((DOMString or object) arg);
+ // Using an enum in a union. Note that we use some enum not declared in our
+ // binding file, because UnionTypes.h will need to include the binding header
+ // for this enum. Pick an enum from an interface that won't drag in too much
+ // stuff.
+ undefined passUnionWithEnum((SupportedType or object) arg);
+
+ // Trying to use a callback in a union won't include the test
+ // headers, unfortunately, so won't compile.
+ // undefined passUnionWithCallback((TestCallback or long) arg);
+ undefined passUnionWithObject((object or long) arg);
+ //undefined passUnionWithDict((Dict or long) arg);
+
+ undefined passUnionWithDefaultValue1(optional (double or DOMString) arg = "");
+ undefined passUnionWithDefaultValue2(optional (double or DOMString) arg = 1);
+ undefined passUnionWithDefaultValue3(optional (double or DOMString) arg = 1.5);
+ undefined passUnionWithDefaultValue4(optional (float or DOMString) arg = "");
+ undefined passUnionWithDefaultValue5(optional (float or DOMString) arg = 1);
+ undefined passUnionWithDefaultValue6(optional (float or DOMString) arg = 1.5);
+ undefined passUnionWithDefaultValue7(optional (unrestricted double or DOMString) arg = "");
+ undefined passUnionWithDefaultValue8(optional (unrestricted double or DOMString) arg = 1);
+ undefined passUnionWithDefaultValue9(optional (unrestricted double or DOMString) arg = 1.5);
+ undefined passUnionWithDefaultValue10(optional (unrestricted double or DOMString) arg = Infinity);
+ undefined passUnionWithDefaultValue11(optional (unrestricted float or DOMString) arg = "");
+ undefined passUnionWithDefaultValue12(optional (unrestricted float or DOMString) arg = 1);
+ undefined passUnionWithDefaultValue13(optional (unrestricted float or DOMString) arg = Infinity);
+ undefined passUnionWithDefaultValue14(optional (double or ByteString) arg = "");
+ undefined passUnionWithDefaultValue15(optional (double or ByteString) arg = 1);
+ undefined passUnionWithDefaultValue16(optional (double or ByteString) arg = 1.5);
+ undefined passUnionWithDefaultValue17(optional (double or SupportedType) arg = "text/html");
+ undefined passUnionWithDefaultValue18(optional (double or SupportedType) arg = 1);
+ undefined passUnionWithDefaultValue19(optional (double or SupportedType) arg = 1.5);
+ undefined passUnionWithDefaultValue20(optional (double or USVString) arg = "abc");
+ undefined passUnionWithDefaultValue21(optional (double or USVString) arg = 1);
+ undefined passUnionWithDefaultValue22(optional (double or USVString) arg = 1.5);
+ undefined passUnionWithDefaultValue23(optional (double or UTF8String) arg = "");
+ undefined passUnionWithDefaultValue24(optional (double or UTF8String) arg = 1);
+ undefined passUnionWithDefaultValue25(optional (double or UTF8String) arg = 1.5);
+
+ undefined passNullableUnionWithDefaultValue1(optional (double or DOMString)? arg = "");
+ undefined passNullableUnionWithDefaultValue2(optional (double or DOMString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue3(optional (double or DOMString)? arg = null);
+ undefined passNullableUnionWithDefaultValue4(optional (float or DOMString)? arg = "");
+ undefined passNullableUnionWithDefaultValue5(optional (float or DOMString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue6(optional (float or DOMString)? arg = null);
+ undefined passNullableUnionWithDefaultValue7(optional (unrestricted double or DOMString)? arg = "");
+ undefined passNullableUnionWithDefaultValue8(optional (unrestricted double or DOMString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue9(optional (unrestricted double or DOMString)? arg = null);
+ undefined passNullableUnionWithDefaultValue10(optional (unrestricted float or DOMString)? arg = "");
+ undefined passNullableUnionWithDefaultValue11(optional (unrestricted float or DOMString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue12(optional (unrestricted float or DOMString)? arg = null);
+ undefined passNullableUnionWithDefaultValue13(optional (double or ByteString)? arg = "");
+ undefined passNullableUnionWithDefaultValue14(optional (double or ByteString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue15(optional (double or ByteString)? arg = 1.5);
+ undefined passNullableUnionWithDefaultValue16(optional (double or ByteString)? arg = null);
+ undefined passNullableUnionWithDefaultValue17(optional (double or SupportedType)? arg = "text/html");
+ undefined passNullableUnionWithDefaultValue18(optional (double or SupportedType)? arg = 1);
+ undefined passNullableUnionWithDefaultValue19(optional (double or SupportedType)? arg = 1.5);
+ undefined passNullableUnionWithDefaultValue20(optional (double or SupportedType)? arg = null);
+ undefined passNullableUnionWithDefaultValue21(optional (double or USVString)? arg = "abc");
+ undefined passNullableUnionWithDefaultValue22(optional (double or USVString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue23(optional (double or USVString)? arg = 1.5);
+ undefined passNullableUnionWithDefaultValue24(optional (double or USVString)? arg = null);
+ undefined passNullableUnionWithDefaultValue25(optional (double or UTF8String)? arg = "");
+ undefined passNullableUnionWithDefaultValue26(optional (double or UTF8String)? arg = 1);
+ undefined passNullableUnionWithDefaultValue27(optional (double or UTF8String)? arg = 1.5);
+ undefined passNullableUnionWithDefaultValue28(optional (double or UTF8String)? arg = null);
+
+ undefined passSequenceOfUnions(sequence<(CanvasPattern or CanvasGradient)> arg);
+ undefined passSequenceOfUnions2(sequence<(object or long)> arg);
+ undefined passVariadicUnion((CanvasPattern or CanvasGradient)... arg);
+
+ undefined passSequenceOfNullableUnions(sequence<(CanvasPattern or CanvasGradient)?> arg);
+ undefined passVariadicNullableUnion((CanvasPattern or CanvasGradient)?... arg);
+ undefined passRecordOfUnions(record<DOMString, (CanvasPattern or CanvasGradient)> arg);
+ // XXXbz no move constructor on some unions
+ // undefined passRecordOfUnions2(record<DOMString, (object or long)> arg);
+
+ (CanvasPattern or CanvasGradient) receiveUnion();
+ (object or long) receiveUnion2();
+ (CanvasPattern? or CanvasGradient) receiveUnionContainingNull();
+ (CanvasPattern or CanvasGradient)? receiveNullableUnion();
+ (object or long)? receiveNullableUnion2();
+ (undefined or CanvasPattern) receiveUnionWithUndefined();
+ (undefined? or CanvasPattern) receiveUnionWithNullableUndefined();
+ (undefined or CanvasPattern?) receiveUnionWithUndefinedAndNullable();
+ (undefined or CanvasPattern)? receiveNullableUnionWithUndefined();
+
+ attribute (CanvasPattern or CanvasGradient) writableUnion;
+ attribute (CanvasPattern? or CanvasGradient) writableUnionContainingNull;
+ attribute (CanvasPattern or CanvasGradient)? writableNullableUnion;
+ attribute (undefined or CanvasPattern) writableUnionWithUndefined;
+ attribute (undefined? or CanvasPattern) writableUnionWithNullableUndefined;
+ attribute (undefined or CanvasPattern?) writableUnionWithUndefinedAndNullable;
+ attribute (undefined or CanvasPattern)? writableNullableUnionWithUndefined;
+
+ // Promise types
+ undefined passPromise(Promise<any> arg);
+ undefined passOptionalPromise(optional Promise<any> arg);
+ undefined passPromiseSequence(sequence<Promise<any>> arg);
+ Promise<any> receivePromise();
+ Promise<any> receiveAddrefedPromise();
+
+ // ObservableArray types
+ attribute ObservableArray<boolean> booleanObservableArray;
+ attribute ObservableArray<object> objectObservableArray;
+ attribute ObservableArray<any> anyObservableArray;
+ attribute ObservableArray<TestInterface> interfaceObservableArray;
+ attribute ObservableArray<long?> nullableObservableArray;
+
+ // binaryNames tests
+ [BinaryName="methodRenamedTo"]
+ undefined methodRenamedFrom();
+ [BinaryName="methodRenamedTo"]
+ undefined methodRenamedFrom(byte argument);
+ [BinaryName="attributeGetterRenamedTo"]
+ readonly attribute byte attributeGetterRenamedFrom;
+ [BinaryName="attributeRenamedTo"]
+ attribute byte attributeRenamedFrom;
+
+ undefined passDictionary(optional Dict x = {});
+ undefined passDictionary2(Dict x);
+ [Cached, Pure]
+ readonly attribute Dict readonlyDictionary;
+ [Cached, Pure]
+ readonly attribute Dict? readonlyNullableDictionary;
+ [Cached, Pure]
+ attribute Dict writableDictionary;
+ [Cached, Pure, Frozen]
+ readonly attribute Dict readonlyFrozenDictionary;
+ [Cached, Pure, Frozen]
+ readonly attribute Dict? readonlyFrozenNullableDictionary;
+ [Cached, Pure, Frozen]
+ attribute Dict writableFrozenDictionary;
+ Dict receiveDictionary();
+ Dict? receiveNullableDictionary();
+ undefined passOtherDictionary(optional GrandparentDict x = {});
+ undefined passSequenceOfDictionaries(sequence<Dict> x);
+ undefined passRecordOfDictionaries(record<DOMString, GrandparentDict> x);
+ // No support for nullable dictionaries inside a sequence (nor should there be)
+ // undefined passSequenceOfNullableDictionaries(sequence<Dict?> x);
+ undefined passDictionaryOrLong(optional Dict x = {});
+ undefined passDictionaryOrLong(long x);
+
+ undefined passDictContainingDict(optional DictContainingDict arg = {});
+ undefined passDictContainingSequence(optional DictContainingSequence arg = {});
+ DictContainingSequence receiveDictContainingSequence();
+ undefined passVariadicDictionary(Dict... arg);
+
+ // EnforceRange/Clamp tests
+ undefined dontEnforceRangeOrClamp(byte arg);
+ undefined doEnforceRange([EnforceRange] byte arg);
+ undefined doEnforceRangeNullable([EnforceRange] byte? arg);
+ undefined doClamp([Clamp] byte arg);
+ undefined doClampNullable([Clamp] byte? arg);
+ attribute [EnforceRange] byte enforcedByte;
+ attribute [EnforceRange] byte? enforcedByteNullable;
+ attribute [Clamp] byte clampedByte;
+ attribute [Clamp] byte? clampedByteNullable;
+
+ // Typedefs
+ const myLong myLongConstant = 5;
+ undefined exerciseTypedefInterfaces1(AnotherNameForTestInterface arg);
+ AnotherNameForTestInterface exerciseTypedefInterfaces2(NullableTestInterface arg);
+ undefined exerciseTypedefInterfaces3(YetAnotherNameForTestInterface arg);
+
+ // Deprecated methods and attributes
+ [Deprecated="Components"]
+ attribute boolean deprecatedAttribute;
+ [Deprecated="Components"]
+ undefined deprecatedMethod(boolean arg);
+ [Deprecated="Components"]
+ undefined deprecatedMethodWithContext(any arg);
+
+ // Static methods and attributes
+ static attribute boolean staticAttribute;
+ static undefined staticMethod(boolean arg);
+ static undefined staticMethodWithContext(any arg);
+
+ // Deprecated methods and attributes;
+ [Deprecated="Components"]
+ static attribute boolean staticDeprecatedAttribute;
+ [Deprecated="Components"]
+ static undefined staticDeprecatedMethod(boolean arg);
+ [Deprecated="Components"]
+ static undefined staticDeprecatedMethodWithContext(any arg);
+
+ // Overload resolution tests
+ //undefined overload1(DOMString... strs);
+ boolean overload1(TestInterface arg);
+ TestInterface overload1(DOMString strs, TestInterface arg);
+ undefined overload2(TestInterface arg);
+ undefined overload2(optional Dict arg = {});
+ undefined overload2(boolean arg);
+ undefined overload2(DOMString arg);
+ undefined overload3(TestInterface arg);
+ undefined overload3(TestCallback arg);
+ undefined overload3(boolean arg);
+ undefined overload4(TestInterface arg);
+ undefined overload4(TestCallbackInterface arg);
+ undefined overload4(DOMString arg);
+ undefined overload5(long arg);
+ undefined overload5(TestEnum arg);
+ undefined overload6(long arg);
+ undefined overload6(boolean arg);
+ undefined overload7(long arg);
+ undefined overload7(boolean arg);
+ undefined overload7(ByteString arg);
+ undefined overload8(long arg);
+ undefined overload8(TestInterface arg);
+ undefined overload9(long? arg);
+ undefined overload9(DOMString arg);
+ undefined overload10(long? arg);
+ undefined overload10(object arg);
+ undefined overload11(long arg);
+ undefined overload11(DOMString? arg);
+ undefined overload12(long arg);
+ undefined overload12(boolean? arg);
+ undefined overload13(long? arg);
+ undefined overload13(boolean arg);
+ undefined overload14(optional long arg);
+ undefined overload14(TestInterface arg);
+ undefined overload15(long arg);
+ undefined overload15(optional TestInterface arg);
+ undefined overload16(long arg);
+ undefined overload16(optional TestInterface? arg);
+ undefined overload17(sequence<long> arg);
+ undefined overload17(record<DOMString, long> arg);
+ undefined overload18(record<DOMString, DOMString> arg);
+ undefined overload18(sequence<DOMString> arg);
+ undefined overload19(sequence<long> arg);
+ undefined overload19(optional Dict arg = {});
+ undefined overload20(optional Dict arg = {});
+ undefined overload20(sequence<long> arg);
+
+ // Variadic handling
+ undefined passVariadicThirdArg(DOMString arg1, long arg2, TestInterface... arg3);
+
+ // Conditionally exposed methods/attributes
+ [Pref="dom.webidl.test1"]
+ readonly attribute boolean prefable1;
+ [Pref="dom.webidl.test1"]
+ readonly attribute boolean prefable2;
+ [Pref="dom.webidl.test2"]
+ readonly attribute boolean prefable3;
+ [Pref="dom.webidl.test2"]
+ readonly attribute boolean prefable4;
+ [Pref="dom.webidl.test1"]
+ readonly attribute boolean prefable5;
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean prefable6;
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean prefable7;
+ [Pref="dom.webidl.test2", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean prefable8;
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean prefable9;
+ [Pref="dom.webidl.test1"]
+ undefined prefable10();
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ undefined prefable11();
+ [Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ readonly attribute boolean prefable12;
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ undefined prefable13();
+ [Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ readonly attribute boolean prefable14;
+ [Func="TestFuncControlledMember"]
+ readonly attribute boolean prefable15;
+ [Func="TestFuncControlledMember"]
+ readonly attribute boolean prefable16;
+ [Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ undefined prefable17();
+ [Func="TestFuncControlledMember"]
+ undefined prefable18();
+ [Func="TestFuncControlledMember"]
+ undefined prefable19();
+ [Trial="TestTrial"]
+ undefined prefable20();
+ [Trial="TestTrial"]
+ readonly attribute boolean prefable21;
+ [Trial="TestTrial", Func="TestFuncControlledMember"]
+ readonly attribute boolean prefable22;
+
+ // Conditionally exposed methods/attributes involving [SecureContext]
+ [SecureContext]
+ readonly attribute boolean conditionalOnSecureContext1;
+ [SecureContext, Pref="dom.webidl.test1"]
+ readonly attribute boolean conditionalOnSecureContext2;
+ [SecureContext, Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean conditionalOnSecureContext3;
+ [SecureContext, Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ readonly attribute boolean conditionalOnSecureContext4;
+ [SecureContext]
+ undefined conditionalOnSecureContext5();
+ [SecureContext, Pref="dom.webidl.test1"]
+ undefined conditionalOnSecureContext6();
+ [SecureContext, Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ undefined conditionalOnSecureContext7();
+ [SecureContext, Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ undefined conditionalOnSecureContext8();
+ [SecureContext, Trial="TestTrial"]
+ readonly attribute boolean conditionalOnSecureContext9;
+ [SecureContext, Trial="TestTrial"]
+ undefined conditionalOnSecureContext10();
+
+ // Miscellania
+ [LegacyLenientThis] attribute long attrWithLenientThis;
+ [LegacyUnforgeable] readonly attribute long unforgeableAttr;
+ [LegacyUnforgeable, ChromeOnly] readonly attribute long unforgeableAttr2;
+ [LegacyUnforgeable] long unforgeableMethod();
+ [LegacyUnforgeable, ChromeOnly] long unforgeableMethod2();
+ stringifier;
+ undefined passRenamedInterface(TestRenamedInterface arg);
+ [PutForwards=writableByte] readonly attribute TestExampleInterface putForwardsAttr;
+ [PutForwards=writableByte, LegacyLenientThis] readonly attribute TestExampleInterface putForwardsAttr2;
+ [PutForwards=writableByte, ChromeOnly] readonly attribute TestExampleInterface putForwardsAttr3;
+ [Throws] undefined throwingMethod();
+ [Throws] attribute boolean throwingAttr;
+ [GetterThrows] attribute boolean throwingGetterAttr;
+ [SetterThrows] attribute boolean throwingSetterAttr;
+ [CanOOM] undefined canOOMMethod();
+ [CanOOM] attribute boolean canOOMAttr;
+ [GetterCanOOM] attribute boolean canOOMGetterAttr;
+ [SetterCanOOM] attribute boolean canOOMSetterAttr;
+ [NeedsSubjectPrincipal] undefined needsSubjectPrincipalMethod();
+ [NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
+ [NeedsSubjectPrincipal=NonSystem] undefined needsNonSystemSubjectPrincipalMethod();
+ [NeedsSubjectPrincipal=NonSystem] attribute boolean needsNonSystemSubjectPrincipalAttr;
+ [NeedsCallerType] undefined needsCallerTypeMethod();
+ [NeedsCallerType] attribute boolean needsCallerTypeAttr;
+ [CEReactions] undefined ceReactionsMethod();
+ [CEReactions] undefined ceReactionsMethodOverload();
+ [CEReactions] undefined ceReactionsMethodOverload(DOMString bar);
+ [CEReactions] attribute boolean ceReactionsAttr;
+ legacycaller short(unsigned long arg1, TestInterface arg2);
+ undefined passArgsWithDefaults(optional long arg1,
+ optional TestInterface? arg2 = null,
+ optional Dict arg3 = {}, optional double arg4 = 5.0,
+ optional float arg5);
+ attribute any toJSONShouldSkipThis;
+ attribute TestParentInterface toJSONShouldSkipThis2;
+ attribute TestCallbackInterface toJSONShouldSkipThis3;
+ [Default] object toJSON();
+
+ attribute byte dashed-attribute;
+ undefined dashed-method();
+
+ // [NonEnumerable] tests
+ [NonEnumerable]
+ attribute boolean nonEnumerableAttr;
+ [NonEnumerable]
+ const boolean nonEnumerableConst = true;
+ [NonEnumerable]
+ undefined nonEnumerableMethod();
+
+ // [AllowShared] tests
+ attribute [AllowShared] ArrayBufferViewTypedef allowSharedArrayBufferViewTypedef;
+ attribute [AllowShared] ArrayBufferView allowSharedArrayBufferView;
+ attribute [AllowShared] ArrayBufferView? allowSharedNullableArrayBufferView;
+ attribute [AllowShared] ArrayBuffer allowSharedArrayBuffer;
+ attribute [AllowShared] ArrayBuffer? allowSharedNullableArrayBuffer;
+
+ undefined passAllowSharedArrayBufferViewTypedef(AllowSharedArrayBufferViewTypedef foo);
+ undefined passAllowSharedArrayBufferView([AllowShared] ArrayBufferView foo);
+ undefined passAllowSharedNullableArrayBufferView([AllowShared] ArrayBufferView? foo);
+ undefined passAllowSharedArrayBuffer([AllowShared] ArrayBuffer foo);
+ undefined passAllowSharedNullableArrayBuffer([AllowShared] ArrayBuffer? foo);
+ undefined passUnionArrayBuffer((DOMString or ArrayBuffer) foo);
+ undefined passUnionAllowSharedArrayBuffer((DOMString or [AllowShared] ArrayBuffer) foo);
+
+ // If you add things here, add them to TestCodeGen and TestJSImplGen as well
+};
+
+[Exposed=Window]
+interface TestExampleProxyInterface {
+ getter long longIndexedGetter(unsigned long ix);
+ setter undefined longIndexedSetter(unsigned long y, long z);
+ readonly attribute unsigned long length;
+ stringifier DOMString myStringifier();
+ getter short shortNameGetter(DOMString nom);
+ deleter undefined (DOMString nomnom);
+ setter undefined shortNamedSetter(DOMString me, short value);
+};
+
+[Exposed=(Window,Worker)]
+interface TestExampleWorkerInterface {
+ [NeedsSubjectPrincipal] undefined needsSubjectPrincipalMethod();
+ [NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
+ [NeedsCallerType] undefined needsCallerTypeMethod();
+ [NeedsCallerType] attribute boolean needsCallerTypeAttr;
+ [NeedsSubjectPrincipal=NonSystem] undefined needsNonSystemSubjectPrincipalMethod();
+ [NeedsSubjectPrincipal=NonSystem] attribute boolean needsNonSystemSubjectPrincipalAttr;
+};
+
+[Exposed=Window]
+interface TestExampleThrowingConstructorInterface {
+ [Throws]
+ constructor();
+ [Throws]
+ constructor(DOMString str);
+ [Throws]
+ constructor(unsigned long num, boolean? boolArg);
+ [Throws]
+ constructor(TestInterface? iface);
+ [Throws]
+ constructor(unsigned long arg1, TestInterface iface);
+ [Throws]
+ constructor(ArrayBuffer arrayBuf);
+ [Throws]
+ constructor(Uint8Array typedArr);
+ // [Throws] constructor(long arg1, long arg2, (TestInterface or OnlyForUseInConstructor) arg3);
+};
diff --git a/dom/bindings/test/TestFunctions.cpp b/dom/bindings/test/TestFunctions.cpp
new file mode 100644
index 0000000000..a91121eaa7
--- /dev/null
+++ b/dom/bindings/test/TestFunctions.cpp
@@ -0,0 +1,315 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/dom/BindingUtils.h"
+#include "mozilla/dom/Document.h"
+#include "mozilla/dom/TestFunctions.h"
+#include "mozilla/dom/TestFunctionsBinding.h"
+#include "mozilla/dom/WindowBinding.h"
+#include "mozilla/dom/WrapperCachedNonISupportsTestInterface.h"
+#include "nsStringBuffer.h"
+#include "mozITestInterfaceJS.h"
+#include "nsComponentManagerUtils.h"
+#include "nsGlobalWindowInner.h"
+
+namespace mozilla::dom {
+
+/* static */
+UniquePtr<TestFunctions> TestFunctions::Constructor(GlobalObject& aGlobal) {
+ return MakeUnique<TestFunctions>();
+}
+
+/* static */
+void TestFunctions::ThrowUncatchableException(GlobalObject& aGlobal,
+ ErrorResult& aRv) {
+ aRv.ThrowUncatchableException();
+}
+
+/* static */
+Promise* TestFunctions::PassThroughPromise(GlobalObject& aGlobal,
+ Promise& aPromise) {
+ return &aPromise;
+}
+
+/* static */
+already_AddRefed<Promise> TestFunctions::PassThroughCallbackPromise(
+ GlobalObject& aGlobal, PromiseReturner& aCallback, ErrorResult& aRv) {
+ return aCallback.Call(aRv);
+}
+
+void TestFunctions::SetStringData(const nsAString& aString) {
+ mStringData = aString;
+}
+
+void TestFunctions::GetStringDataAsAString(nsAString& aString) {
+ aString = mStringData;
+}
+
+void TestFunctions::GetStringDataAsAString(uint32_t aLength,
+ nsAString& aString) {
+ MOZ_RELEASE_ASSERT(aLength <= mStringData.Length(),
+ "Bogus test passing in a too-big length");
+ aString.Assign(mStringData.BeginReading(), aLength);
+}
+
+void TestFunctions::GetStringDataAsDOMString(const Optional<uint32_t>& aLength,
+ DOMString& aString) {
+ uint32_t length;
+ if (aLength.WasPassed()) {
+ length = aLength.Value();
+ MOZ_RELEASE_ASSERT(length <= mStringData.Length(),
+ "Bogus test passing in a too-big length");
+ } else {
+ length = mStringData.Length();
+ }
+
+ nsStringBuffer* buf = nsStringBuffer::FromString(mStringData);
+ if (buf) {
+ aString.SetKnownLiveStringBuffer(buf, length);
+ return;
+ }
+
+ // We better have an empty mStringData; otherwise why did we not have a string
+ // buffer?
+ MOZ_RELEASE_ASSERT(length == 0, "Why no stringbuffer?");
+ // No need to do anything here; aString is already empty.
+}
+
+void TestFunctions::GetShortLiteralString(nsAString& aString) {
+ // JS inline strings can hold 2 * sizeof(void*) chars, which on 32-bit means 8
+ // chars. Return fewer than that.
+ aString.AssignLiteral(u"012345");
+}
+
+void TestFunctions::GetMediumLiteralString(nsAString& aString) {
+ // JS inline strings are at most 2 * sizeof(void*) chars, so at most 16 on
+ // 64-bit. FakeString can hold 63 chars in its inline buffer (plus the null
+ // terminator). Let's return 40 chars; that way if we ever move to 128-bit
+ // void* or something this test will still be valid.
+ aString.AssignLiteral(u"0123456789012345678901234567890123456789");
+}
+
+void TestFunctions::GetLongLiteralString(nsAString& aString) {
+ // Need more than 64 chars.
+ aString.AssignLiteral(
+ u"0123456789012345678901234567890123456789" // 40
+ "0123456789012345678901234567890123456789" // 80
+ );
+}
+
+void TestFunctions::GetStringbufferString(const nsAString& aInput,
+ nsAString& aRetval) {
+ // We have to be a bit careful: if aRetval is an autostring, if we just assign
+ // it won't cause stringbuffer allocation. So we have to round-trip through
+ // something that definitely causes a stringbuffer allocation.
+ nsString str;
+ // Can't use operator= here, because if aInput is a literal string then str
+ // would end up the same way.
+ str.Assign(aInput.BeginReading(), aInput.Length());
+
+ // Now we might end up hitting our external string cache and getting the wrong
+ // sort of external string, so replace the last char by a different value
+ // (replacing, not just appending, to preserve the length). If we have an
+ // empty string, our caller screwed up and there's not much we can do for
+ // them.
+ if (str.Length() > 1) {
+ char16_t last = str[str.Length() - 1];
+ str.Truncate(str.Length() - 1);
+ if (last == 'x') {
+ str.Append('y');
+ } else {
+ str.Append('x');
+ }
+ }
+
+ // Here we use operator= to preserve stringbufferness.
+ aRetval = str;
+}
+
+StringType TestFunctions::GetStringType(const nsAString& aString) {
+ if (aString.IsLiteral()) {
+ return StringType::Literal;
+ }
+
+ if (nsStringBuffer::FromString(aString)) {
+ return StringType::Stringbuffer;
+ }
+
+ if (aString.GetDataFlags() & nsAString::DataFlags::INLINE) {
+ return StringType::Inline;
+ }
+
+ return StringType::Other;
+}
+
+bool TestFunctions::StringbufferMatchesStored(const nsAString& aString) {
+ return nsStringBuffer::FromString(aString) &&
+ nsStringBuffer::FromString(aString) ==
+ nsStringBuffer::FromString(mStringData);
+}
+
+void TestFunctions::TestThrowNsresult(ErrorResult& aError) {
+ nsCOMPtr<mozITestInterfaceJS> impl =
+ do_CreateInstance("@mozilla.org/dom/test-interface-js;1");
+ aError = impl->TestThrowNsresult();
+}
+
+void TestFunctions::TestThrowNsresultFromNative(ErrorResult& aError) {
+ nsCOMPtr<mozITestInterfaceJS> impl =
+ do_CreateInstance("@mozilla.org/dom/test-interface-js;1");
+ aError = impl->TestThrowNsresultFromNative();
+}
+
+already_AddRefed<Promise> TestFunctions::ThrowToRejectPromise(
+ GlobalObject& aGlobal, ErrorResult& aError) {
+ aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+ return nullptr;
+}
+
+int32_t TestFunctions::One() const { return 1; }
+
+int32_t TestFunctions::Two() const { return 2; }
+
+void TestFunctions::SetClampedNullableOctet(const Nullable<uint8_t>& aOctet) {
+ mClampedNullableOctet = aOctet;
+}
+
+Nullable<uint8_t> TestFunctions::GetClampedNullableOctet() const {
+ return mClampedNullableOctet;
+}
+
+void TestFunctions::SetEnforcedNullableOctet(const Nullable<uint8_t>& aOctet) {
+ mEnforcedNullableOctet = aOctet;
+}
+
+Nullable<uint8_t> TestFunctions::GetEnforcedNullableOctet() const {
+ return mEnforcedNullableOctet;
+}
+
+void TestFunctions::SetArrayBufferView(const ArrayBufferView& aBuffer) {}
+
+void TestFunctions::GetArrayBufferView(JSContext* aCx,
+ JS::Handle<JSObject*> aObj,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aError) {
+ aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+void TestFunctions::SetAllowSharedArrayBufferView(
+ const ArrayBufferView& aBuffer) {}
+
+void TestFunctions::GetAllowSharedArrayBufferView(
+ JSContext* aCx, JS::Handle<JSObject*> aObj,
+ JS::MutableHandle<JSObject*> aRetval, ErrorResult& aError) {
+ aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+void TestFunctions::SetSequenceOfArrayBufferView(
+ const Sequence<ArrayBufferView>& aBuffers) {}
+
+void TestFunctions::GetSequenceOfArrayBufferView(JSContext* aCx,
+ JS::Handle<JSObject*> aObj,
+ nsTArray<JSObject*>& aRetval,
+ ErrorResult& aError) {
+ aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+void TestFunctions::SetSequenceOfAllowSharedArrayBufferView(
+ const Sequence<ArrayBufferView>& aBuffers) {}
+
+void TestFunctions::GetSequenceOfAllowSharedArrayBufferView(
+ JSContext* aCx, JS::Handle<JSObject*> aObj, nsTArray<JSObject*>& aRetval,
+ ErrorResult& aError) {
+ aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+void TestFunctions::SetArrayBuffer(const ArrayBuffer& aBuffer) {}
+
+void TestFunctions::GetArrayBuffer(JSContext* aCx, JS::Handle<JSObject*> aObj,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aError) {
+ aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+void TestFunctions::SetAllowSharedArrayBuffer(const ArrayBuffer& aBuffer) {}
+
+void TestFunctions::GetAllowSharedArrayBuffer(
+ JSContext* aCx, JS::Handle<JSObject*> aObj,
+ JS::MutableHandle<JSObject*> aRetval, ErrorResult& aError) {
+ aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+void TestFunctions::SetSequenceOfArrayBuffer(
+ const Sequence<ArrayBuffer>& aBuffers) {}
+
+void TestFunctions::GetSequenceOfArrayBuffer(JSContext* aCx,
+ JS::Handle<JSObject*> aObj,
+ nsTArray<JSObject*>& aRetval,
+ ErrorResult& aError) {
+ aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+void TestFunctions::SetSequenceOfAllowSharedArrayBuffer(
+ const Sequence<ArrayBuffer>& aBuffers) {}
+
+void TestFunctions::GetSequenceOfAllowSharedArrayBuffer(
+ JSContext* aCx, JS::Handle<JSObject*> aObj, nsTArray<JSObject*>& aRetval,
+ ErrorResult& aError) {
+ aError.Throw(NS_ERROR_NOT_IMPLEMENTED);
+}
+
+void TestFunctions::TestNotAllowShared(const ArrayBufferView& aBuffer) {}
+
+void TestFunctions::TestNotAllowShared(const ArrayBuffer& aBuffer) {}
+
+void TestFunctions::TestNotAllowShared(const nsAString& aBuffer) {}
+
+void TestFunctions::TestAllowShared(const ArrayBufferView& aBuffer) {}
+
+void TestFunctions::TestAllowShared(const ArrayBuffer& aBuffer) {}
+
+void TestFunctions::TestDictWithAllowShared(
+ const DictWithAllowSharedBufferSource& aDict) {}
+
+void TestFunctions::TestUnionOfBuffferSource(
+ const ArrayBufferOrArrayBufferViewOrString& aUnion) {}
+
+void TestFunctions::TestUnionOfAllowSharedBuffferSource(
+ const MaybeSharedArrayBufferOrMaybeSharedArrayBufferView& aUnion) {}
+
+bool TestFunctions::ObjectFromAboutBlank(JSContext* aCx, JSObject* aObj) {
+ // We purposefully don't use WindowOrNull here, because we want to
+ // demonstrate the incorrect behavior we get, not just fail some asserts.
+ RefPtr<nsGlobalWindowInner> win;
+ UNWRAP_MAYBE_CROSS_ORIGIN_OBJECT(Window, aObj, win, aCx);
+ if (!win) {
+ return false;
+ }
+
+ Document* doc = win->GetDoc();
+ if (!doc) {
+ return false;
+ }
+
+ return doc->GetDocumentURI()->GetSpecOrDefault().EqualsLiteral("about:blank");
+}
+
+WrapperCachedNonISupportsTestInterface*
+TestFunctions::WrapperCachedNonISupportsObject() {
+ if (!mWrapperCachedNonISupportsTestInterface) {
+ mWrapperCachedNonISupportsTestInterface =
+ new WrapperCachedNonISupportsTestInterface();
+ }
+ return mWrapperCachedNonISupportsTestInterface;
+}
+
+bool TestFunctions::WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto,
+ JS::MutableHandle<JSObject*> aWrapper) {
+ return TestFunctions_Binding::Wrap(aCx, this, aGivenProto, aWrapper);
+}
+
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestFunctions.h b/dom/bindings/test/TestFunctions.h
new file mode 100644
index 0000000000..cec3f3136e
--- /dev/null
+++ b/dom/bindings/test/TestFunctions.h
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestFunctions_h
+#define mozilla_dom_TestFunctions_h
+
+#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/NonRefcountedDOMObject.h"
+#include "mozilla/dom/TestFunctionsBinding.h"
+#include "nsString.h"
+
+namespace mozilla {
+namespace dom {
+
+class Promise;
+class PromiseReturner;
+class WrapperCachedNonISupportsTestInterface;
+
+class TestFunctions : public NonRefcountedDOMObject {
+ public:
+ static UniquePtr<TestFunctions> Constructor(GlobalObject& aGlobal);
+
+ static void ThrowUncatchableException(GlobalObject& aGlobal,
+ ErrorResult& aRv);
+
+ static Promise* PassThroughPromise(GlobalObject& aGlobal, Promise& aPromise);
+
+ MOZ_CAN_RUN_SCRIPT
+ static already_AddRefed<Promise> PassThroughCallbackPromise(
+ GlobalObject& aGlobal, PromiseReturner& aCallback, ErrorResult& aRv);
+
+ void SetStringData(const nsAString& aString);
+
+ void GetStringDataAsAString(nsAString& aString);
+ void GetStringDataAsAString(uint32_t aLength, nsAString& aString);
+ void GetStringDataAsDOMString(const Optional<uint32_t>& aLength,
+ DOMString& aString);
+
+ void GetShortLiteralString(nsAString& aString);
+ void GetMediumLiteralString(nsAString& aString);
+ void GetLongLiteralString(nsAString& aString);
+
+ void GetStringbufferString(const nsAString& aInput, nsAString& aRetval);
+
+ StringType GetStringType(const nsAString& aString);
+
+ bool StringbufferMatchesStored(const nsAString& aString);
+
+ void TestThrowNsresult(ErrorResult& aError);
+ void TestThrowNsresultFromNative(ErrorResult& aError);
+ static already_AddRefed<Promise> ThrowToRejectPromise(GlobalObject& aGlobal,
+ ErrorResult& aError);
+
+ int32_t One() const;
+ int32_t Two() const;
+
+ void SetClampedNullableOctet(const Nullable<uint8_t>& aOctet);
+ Nullable<uint8_t> GetClampedNullableOctet() const;
+ void SetEnforcedNullableOctet(const Nullable<uint8_t>& aOctet);
+ Nullable<uint8_t> GetEnforcedNullableOctet() const;
+
+ void SetArrayBufferView(const ArrayBufferView& aBuffer);
+ void GetArrayBufferView(JSContext* aCx, JS::Handle<JSObject*> aObj,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aError);
+ void SetAllowSharedArrayBufferView(const ArrayBufferView& aBuffer);
+ void GetAllowSharedArrayBufferView(JSContext* aCx, JS::Handle<JSObject*> aObj,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aError);
+ void SetSequenceOfArrayBufferView(const Sequence<ArrayBufferView>& aBuffers);
+ void GetSequenceOfArrayBufferView(JSContext* aCx, JS::Handle<JSObject*> aObj,
+ nsTArray<JSObject*>& aRetval,
+ ErrorResult& aError);
+ void SetSequenceOfAllowSharedArrayBufferView(
+ const Sequence<ArrayBufferView>& aBuffers);
+ void GetSequenceOfAllowSharedArrayBufferView(JSContext* aCx,
+ JS::Handle<JSObject*> aObj,
+ nsTArray<JSObject*>& aRetval,
+ ErrorResult& aError);
+ void SetArrayBuffer(const ArrayBuffer& aBuffer);
+ void GetArrayBuffer(JSContext* aCx, JS::Handle<JSObject*> aObj,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aError);
+ void SetAllowSharedArrayBuffer(const ArrayBuffer& aBuffer);
+ void GetAllowSharedArrayBuffer(JSContext* aCx, JS::Handle<JSObject*> aObj,
+ JS::MutableHandle<JSObject*> aRetval,
+ ErrorResult& aError);
+ void SetSequenceOfArrayBuffer(const Sequence<ArrayBuffer>& aBuffers);
+ void GetSequenceOfArrayBuffer(JSContext* aCx, JS::Handle<JSObject*> aObj,
+ nsTArray<JSObject*>& aRetval,
+ ErrorResult& aError);
+ void SetSequenceOfAllowSharedArrayBuffer(
+ const Sequence<ArrayBuffer>& aBuffers);
+ void GetSequenceOfAllowSharedArrayBuffer(JSContext* aCx,
+ JS::Handle<JSObject*> aObj,
+ nsTArray<JSObject*>& aRetval,
+ ErrorResult& aError);
+ void TestNotAllowShared(const ArrayBufferView& aBuffer);
+ void TestNotAllowShared(const ArrayBuffer& aBuffer);
+ void TestNotAllowShared(const nsAString& aBuffer);
+ void TestAllowShared(const ArrayBufferView& aBuffer);
+ void TestAllowShared(const ArrayBuffer& aBuffer);
+ void TestDictWithAllowShared(const DictWithAllowSharedBufferSource& aDict);
+ void TestUnionOfBuffferSource(
+ const ArrayBufferOrArrayBufferViewOrString& aUnion);
+ void TestUnionOfAllowSharedBuffferSource(
+ const MaybeSharedArrayBufferOrMaybeSharedArrayBufferView& aUnion);
+
+ bool StaticAndNonStaticOverload() { return false; }
+ static bool StaticAndNonStaticOverload(GlobalObject& aGlobal,
+ const Optional<uint32_t>& aLength) {
+ return true;
+ }
+
+ static bool ObjectFromAboutBlank(JSContext* aCx, JSObject* aObj);
+
+ WrapperCachedNonISupportsTestInterface* WrapperCachedNonISupportsObject();
+
+ bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto,
+ JS::MutableHandle<JSObject*> aWrapper);
+
+ private:
+ nsString mStringData;
+ RefPtr<WrapperCachedNonISupportsTestInterface>
+ mWrapperCachedNonISupportsTestInterface;
+
+ Nullable<uint8_t> mClampedNullableOctet;
+ Nullable<uint8_t> mEnforcedNullableOctet;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TestFunctions_h
diff --git a/dom/bindings/test/TestInterfaceAsyncIterableDouble.cpp b/dom/bindings/test/TestInterfaceAsyncIterableDouble.cpp
new file mode 100644
index 0000000000..a0ec0d64f0
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceAsyncIterableDouble.cpp
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/dom/TestInterfaceAsyncIterableDouble.h"
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "nsPIDOMWindow.h"
+#include "mozilla/dom/BindingUtils.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceAsyncIterableDouble, mParent)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceAsyncIterableDouble)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceAsyncIterableDouble)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceAsyncIterableDouble)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+TestInterfaceAsyncIterableDouble::TestInterfaceAsyncIterableDouble(
+ nsPIDOMWindowInner* aParent)
+ : mParent(aParent) {
+ mValues.AppendElement(std::pair<nsString, nsString>(u"a"_ns, u"b"_ns));
+ mValues.AppendElement(std::pair<nsString, nsString>(u"c"_ns, u"d"_ns));
+ mValues.AppendElement(std::pair<nsString, nsString>(u"e"_ns, u"f"_ns));
+}
+
+// static
+already_AddRefed<TestInterfaceAsyncIterableDouble>
+TestInterfaceAsyncIterableDouble::Constructor(const GlobalObject& aGlobal,
+ ErrorResult& aRv) {
+ nsCOMPtr<nsPIDOMWindowInner> window =
+ do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ RefPtr<TestInterfaceAsyncIterableDouble> r =
+ new TestInterfaceAsyncIterableDouble(window);
+ return r.forget();
+}
+
+JSObject* TestInterfaceAsyncIterableDouble::WrapObject(
+ JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
+ return TestInterfaceAsyncIterableDouble_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+nsPIDOMWindowInner* TestInterfaceAsyncIterableDouble::GetParentObject() const {
+ return mParent;
+}
+
+already_AddRefed<Promise>
+TestInterfaceAsyncIterableDouble::GetNextIterationResult(Iterator* aIterator,
+ ErrorResult& aRv) {
+ RefPtr<Promise> promise = Promise::Create(mParent->AsGlobal(), aRv);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return nullptr;
+ }
+
+ NS_DispatchToMainThread(NewRunnableMethod<RefPtr<Iterator>, RefPtr<Promise>>(
+ "TestInterfaceAsyncIterableDouble::GetNextIterationResult", this,
+ &TestInterfaceAsyncIterableDouble::ResolvePromise, aIterator, promise));
+
+ return promise.forget();
+}
+
+void TestInterfaceAsyncIterableDouble::ResolvePromise(Iterator* aIterator,
+ Promise* aPromise) {
+ IteratorData& data = aIterator->Data();
+
+ // Test data: ['a', 'b'], ['c', 'd'], ['e', 'f']
+ uint32_t idx = data.mIndex;
+ if (idx >= mValues.Length()) {
+ iterator_utils::ResolvePromiseForFinished(aPromise);
+ } else {
+ switch (aIterator->GetIteratorType()) {
+ case IterableIteratorBase::IteratorType::Keys:
+ aPromise->MaybeResolve(mValues[idx].first);
+ break;
+ case IterableIteratorBase::IteratorType::Values:
+ aPromise->MaybeResolve(mValues[idx].second);
+ break;
+ case IterableIteratorBase::IteratorType::Entries:
+ iterator_utils::ResolvePromiseWithKeyAndValue(
+ aPromise, mValues[idx].first, mValues[idx].second);
+ break;
+ }
+
+ data.mIndex++;
+ }
+}
+
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestInterfaceAsyncIterableDouble.h b/dom/bindings/test/TestInterfaceAsyncIterableDouble.h
new file mode 100644
index 0000000000..4b458617dc
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceAsyncIterableDouble.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestInterfaceAsyncIterableDouble_h
+#define mozilla_dom_TestInterfaceAsyncIterableDouble_h
+
+#include "IterableIterator.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "nsTArray.h"
+#include "nsWrapperCache.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+
+class ErrorResult;
+
+namespace dom {
+
+class GlobalObject;
+
+// Implementation of test binding for webidl iterable interfaces, using
+// primitives for value type
+class TestInterfaceAsyncIterableDouble final : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(TestInterfaceAsyncIterableDouble)
+
+ explicit TestInterfaceAsyncIterableDouble(nsPIDOMWindowInner* aParent);
+ nsPIDOMWindowInner* GetParentObject() const;
+ virtual JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+ static already_AddRefed<TestInterfaceAsyncIterableDouble> Constructor(
+ const GlobalObject& aGlobal, ErrorResult& rv);
+
+ struct IteratorData {
+ uint32_t mIndex = 0;
+ };
+
+ using Iterator = AsyncIterableIterator<TestInterfaceAsyncIterableDouble>;
+
+ void InitAsyncIteratorData(IteratorData& aData, Iterator::IteratorType aType,
+ ErrorResult& aError) {}
+
+ already_AddRefed<Promise> GetNextIterationResult(Iterator* aIterator,
+ ErrorResult& aRv);
+
+ private:
+ virtual ~TestInterfaceAsyncIterableDouble() = default;
+ void ResolvePromise(Iterator* aIterator, Promise* aPromise);
+
+ nsCOMPtr<nsPIDOMWindowInner> mParent;
+ nsTArray<std::pair<nsString, nsString>> mValues;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TestInterfaceAsyncIterableDouble_h
diff --git a/dom/bindings/test/TestInterfaceAsyncIterableDoubleUnion.cpp b/dom/bindings/test/TestInterfaceAsyncIterableDoubleUnion.cpp
new file mode 100644
index 0000000000..b0b16532ed
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceAsyncIterableDoubleUnion.cpp
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/dom/TestInterfaceAsyncIterableDoubleUnion.h"
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "nsPIDOMWindow.h"
+#include "mozilla/dom/BindingUtils.h"
+#include "mozilla/dom/UnionTypes.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceAsyncIterableDoubleUnion,
+ mParent)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceAsyncIterableDoubleUnion)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceAsyncIterableDoubleUnion)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceAsyncIterableDoubleUnion)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+TestInterfaceAsyncIterableDoubleUnion::TestInterfaceAsyncIterableDoubleUnion(
+ nsPIDOMWindowInner* aParent)
+ : mParent(aParent) {
+ OwningStringOrLong a;
+ a.SetAsLong() = 1;
+ mValues.AppendElement(std::pair<nsString, OwningStringOrLong>(u"long"_ns, a));
+ a.SetAsString() = u"a"_ns;
+ mValues.AppendElement(
+ std::pair<nsString, OwningStringOrLong>(u"string"_ns, a));
+}
+
+// static
+already_AddRefed<TestInterfaceAsyncIterableDoubleUnion>
+TestInterfaceAsyncIterableDoubleUnion::Constructor(const GlobalObject& aGlobal,
+ ErrorResult& aRv) {
+ nsCOMPtr<nsPIDOMWindowInner> window =
+ do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ RefPtr<TestInterfaceAsyncIterableDoubleUnion> r =
+ new TestInterfaceAsyncIterableDoubleUnion(window);
+ return r.forget();
+}
+
+JSObject* TestInterfaceAsyncIterableDoubleUnion::WrapObject(
+ JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
+ return TestInterfaceAsyncIterableDoubleUnion_Binding::Wrap(aCx, this,
+ aGivenProto);
+}
+
+nsPIDOMWindowInner* TestInterfaceAsyncIterableDoubleUnion::GetParentObject()
+ const {
+ return mParent;
+}
+
+already_AddRefed<Promise>
+TestInterfaceAsyncIterableDoubleUnion::GetNextIterationResult(
+ Iterator* aIterator, ErrorResult& aRv) {
+ RefPtr<Promise> promise = Promise::Create(mParent->AsGlobal(), aRv);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return nullptr;
+ }
+
+ NS_DispatchToMainThread(NewRunnableMethod<RefPtr<Iterator>, RefPtr<Promise>>(
+ "TestInterfaceAsyncIterableDoubleUnion::GetNextIterationResult", this,
+ &TestInterfaceAsyncIterableDoubleUnion::ResolvePromise, aIterator,
+ promise));
+
+ return promise.forget();
+}
+
+void TestInterfaceAsyncIterableDoubleUnion::ResolvePromise(Iterator* aIterator,
+ Promise* aPromise) {
+ IteratorData& data = aIterator->Data();
+
+ // Test data:
+ // [long, 1], [string, "a"]
+ uint32_t idx = data.mIndex;
+ if (idx >= mValues.Length()) {
+ iterator_utils::ResolvePromiseForFinished(aPromise);
+ } else {
+ switch (aIterator->GetIteratorType()) {
+ case IterableIteratorBase::IteratorType::Keys:
+ aPromise->MaybeResolve(mValues[idx].first);
+ break;
+ case IterableIteratorBase::IteratorType::Values:
+ aPromise->MaybeResolve(mValues[idx].second);
+ break;
+ case IterableIteratorBase::IteratorType::Entries:
+ iterator_utils::ResolvePromiseWithKeyAndValue(
+ aPromise, mValues[idx].first, mValues[idx].second);
+ break;
+ }
+
+ data.mIndex++;
+ }
+}
+
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestInterfaceAsyncIterableDoubleUnion.h b/dom/bindings/test/TestInterfaceAsyncIterableDoubleUnion.h
new file mode 100644
index 0000000000..902c99b1a9
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceAsyncIterableDoubleUnion.h
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestInterfaceAsyncIterableDoubleUnion_h
+#define mozilla_dom_TestInterfaceAsyncIterableDoubleUnion_h
+
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "IterableIterator.h"
+#include "nsCOMPtr.h"
+#include "nsWrapperCache.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+
+class ErrorResult;
+
+namespace dom {
+
+class GlobalObject;
+
+// Implementation of test binding for webidl iterable interfaces, using
+// primitives for value type
+class TestInterfaceAsyncIterableDoubleUnion final : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(
+ TestInterfaceAsyncIterableDoubleUnion)
+
+ explicit TestInterfaceAsyncIterableDoubleUnion(nsPIDOMWindowInner* aParent);
+ nsPIDOMWindowInner* GetParentObject() const;
+ virtual JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+ static already_AddRefed<TestInterfaceAsyncIterableDoubleUnion> Constructor(
+ const GlobalObject& aGlobal, ErrorResult& rv);
+
+ struct IteratorData {
+ uint32_t mIndex = 0;
+ };
+
+ using Iterator = AsyncIterableIterator<TestInterfaceAsyncIterableDoubleUnion>;
+
+ void InitAsyncIteratorData(IteratorData& aData, Iterator::IteratorType aType,
+ ErrorResult& aError) {}
+
+ already_AddRefed<Promise> GetNextIterationResult(Iterator* aIterator,
+ ErrorResult& aRv);
+
+ private:
+ virtual ~TestInterfaceAsyncIterableDoubleUnion() = default;
+ void ResolvePromise(Iterator* aIterator, Promise* aPromise);
+
+ nsCOMPtr<nsPIDOMWindowInner> mParent;
+ nsTArray<std::pair<nsString, OwningStringOrLong>> mValues;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TestInterfaceAsyncIterableDoubleUnion_h
diff --git a/dom/bindings/test/TestInterfaceAsyncIterableSingle.cpp b/dom/bindings/test/TestInterfaceAsyncIterableSingle.cpp
new file mode 100644
index 0000000000..f8d049b840
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceAsyncIterableSingle.cpp
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/dom/TestInterfaceAsyncIterableSingle.h"
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "nsPIDOMWindow.h"
+#include "mozilla/dom/BindingUtils.h"
+#include "mozilla/dom/IterableIterator.h"
+#include "mozilla/dom/Promise-inl.h"
+#include "nsThreadUtils.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceAsyncIterableSingle, mParent)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceAsyncIterableSingle)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceAsyncIterableSingle)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceAsyncIterableSingle)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+TestInterfaceAsyncIterableSingle::TestInterfaceAsyncIterableSingle(
+ nsPIDOMWindowInner* aParent, bool aFailToInit)
+ : mParent(aParent), mFailToInit(aFailToInit) {}
+
+// static
+already_AddRefed<TestInterfaceAsyncIterableSingle>
+TestInterfaceAsyncIterableSingle::Constructor(
+ const GlobalObject& aGlobal,
+ const TestInterfaceAsyncIterableSingleOptions& aOptions, ErrorResult& aRv) {
+ nsCOMPtr<nsPIDOMWindowInner> window =
+ do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ RefPtr<TestInterfaceAsyncIterableSingle> r =
+ new TestInterfaceAsyncIterableSingle(window, aOptions.mFailToInit);
+ return r.forget();
+}
+
+JSObject* TestInterfaceAsyncIterableSingle::WrapObject(
+ JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
+ return TestInterfaceAsyncIterableSingle_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+nsPIDOMWindowInner* TestInterfaceAsyncIterableSingle::GetParentObject() const {
+ return mParent;
+}
+
+void TestInterfaceAsyncIterableSingle::InitAsyncIteratorData(
+ IteratorData& aData, Iterator::IteratorType aType, ErrorResult& aError) {
+ if (mFailToInit) {
+ aError.ThrowTypeError("Caller asked us to fail");
+ return;
+ }
+
+ // Nothing else to do.
+ MOZ_ASSERT(aData.mIndex == 0);
+ MOZ_ASSERT(aData.mMultiplier == 1);
+}
+
+already_AddRefed<Promise>
+TestInterfaceAsyncIterableSingle::GetNextIterationResult(Iterator* aIterator,
+ ErrorResult& aRv) {
+ return GetNextIterationResult(aIterator, aIterator->Data(), aRv);
+}
+
+already_AddRefed<Promise>
+TestInterfaceAsyncIterableSingle::GetNextIterationResult(
+ IterableIteratorBase* aIterator, IteratorData& aData, ErrorResult& aRv) {
+ RefPtr<Promise> promise = Promise::Create(mParent->AsGlobal(), aRv);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return nullptr;
+ }
+
+ nsCOMPtr<nsIRunnable> callResolvePromise =
+ NewRunnableMethod<RefPtr<IterableIteratorBase>, IteratorData&,
+ RefPtr<Promise>>(
+ "TestInterfaceAsyncIterableSingle::GetNextIterationResult", this,
+ &TestInterfaceAsyncIterableSingle::ResolvePromise, aIterator, aData,
+ promise);
+ if (aData.mBlockingPromisesIndex < aData.mBlockingPromises.Length()) {
+ aData.mBlockingPromises[aData.mBlockingPromisesIndex]
+ ->AddCallbacksWithCycleCollectedArgs(
+ [](JSContext* aCx, JS::Handle<JS::Value> aValue, ErrorResult& aRv,
+ nsIRunnable* aCallResolvePromise) {
+ NS_DispatchToMainThread(aCallResolvePromise);
+ },
+ [](JSContext* aCx, JS::Handle<JS::Value> aValue, ErrorResult& aRv,
+ nsIRunnable* aCallResolvePromise) {},
+ std::move(callResolvePromise));
+ ++aData.mBlockingPromisesIndex;
+ } else {
+ NS_DispatchToMainThread(callResolvePromise);
+ }
+
+ return promise.forget();
+}
+
+void TestInterfaceAsyncIterableSingle::ResolvePromise(
+ IterableIteratorBase* aIterator, IteratorData& aData, Promise* aPromise) {
+ if (aData.mIndex >= 10) {
+ iterator_utils::ResolvePromiseForFinished(aPromise);
+ } else {
+ aPromise->MaybeResolve(int32_t(aData.mIndex * 9 % 7 * aData.mMultiplier));
+
+ aData.mIndex++;
+ }
+}
+
+void TestInterfaceAsyncIterableSingle::IteratorData::Traverse(
+ nsCycleCollectionTraversalCallback& cb) {
+ TestInterfaceAsyncIterableSingle::IteratorData* tmp = this;
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBlockingPromises);
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mThrowFromReturn);
+}
+void TestInterfaceAsyncIterableSingle::IteratorData::Unlink() {
+ TestInterfaceAsyncIterableSingle::IteratorData* tmp = this;
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mBlockingPromises);
+ NS_IMPL_CYCLE_COLLECTION_UNLINK(mThrowFromReturn);
+}
+
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestInterfaceAsyncIterableSingle.h b/dom/bindings/test/TestInterfaceAsyncIterableSingle.h
new file mode 100644
index 0000000000..c92b35cc7b
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceAsyncIterableSingle.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestInterfaceAsyncIterableSingle_h
+#define mozilla_dom_TestInterfaceAsyncIterableSingle_h
+
+#include "IterableIterator.h"
+#include "nsCOMPtr.h"
+#include "nsWrapperCache.h"
+#include "nsTArray.h"
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+
+class ErrorResult;
+
+namespace dom {
+
+class GlobalObject;
+struct TestInterfaceAsyncIterableSingleOptions;
+
+// Implementation of test binding for webidl iterable interfaces, using
+// primitives for value type
+class TestInterfaceAsyncIterableSingle : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(TestInterfaceAsyncIterableSingle)
+
+ explicit TestInterfaceAsyncIterableSingle(nsPIDOMWindowInner* aParent,
+ bool aFailToInit = false);
+ nsPIDOMWindowInner* GetParentObject() const;
+ virtual JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+ static already_AddRefed<TestInterfaceAsyncIterableSingle> Constructor(
+ const GlobalObject& aGlobal,
+ const TestInterfaceAsyncIterableSingleOptions& aOptions, ErrorResult& rv);
+
+ using Iterator = AsyncIterableIterator<TestInterfaceAsyncIterableSingle>;
+ already_AddRefed<Promise> GetNextIterationResult(Iterator* aIterator,
+ ErrorResult& aRv);
+
+ struct IteratorData {
+ void Traverse(nsCycleCollectionTraversalCallback& cb);
+ void Unlink();
+
+ uint32_t mIndex = 0;
+ uint32_t mMultiplier = 1;
+ Sequence<OwningNonNull<Promise>> mBlockingPromises;
+ size_t mBlockingPromisesIndex = 0;
+ uint32_t mFailNextAfter = 4294967295;
+ bool mThrowFromNext = false;
+ RefPtr<TestThrowingCallback> mThrowFromReturn;
+ };
+
+ void InitAsyncIteratorData(IteratorData& aData, Iterator::IteratorType aType,
+ ErrorResult& aError);
+
+ protected:
+ already_AddRefed<Promise> GetNextIterationResult(
+ IterableIteratorBase* aIterator, IteratorData& aData, ErrorResult& aRv);
+
+ virtual ~TestInterfaceAsyncIterableSingle() = default;
+
+ private:
+ void ResolvePromise(IterableIteratorBase* aIterator, IteratorData& aData,
+ Promise* aPromise);
+
+ nsCOMPtr<nsPIDOMWindowInner> mParent;
+ bool mFailToInit;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TestInterfaceAsyncIterableSingle_h
diff --git a/dom/bindings/test/TestInterfaceAsyncIterableSingleWithArgs.cpp b/dom/bindings/test/TestInterfaceAsyncIterableSingleWithArgs.cpp
new file mode 100644
index 0000000000..6c02829186
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceAsyncIterableSingleWithArgs.cpp
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/dom/TestInterfaceAsyncIterableSingleWithArgs.h"
+#include "ScriptSettings.h"
+#include "js/Value.h"
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "nsPIDOMWindow.h"
+#include "mozilla/dom/BindingUtils.h"
+#include "mozilla/dom/IterableIterator.h"
+#include "mozilla/dom/Promise-inl.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_CLASS(TestInterfaceAsyncIterableSingleWithArgs)
+
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(
+ TestInterfaceAsyncIterableSingleWithArgs, TestInterfaceAsyncIterableSingle)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(
+ TestInterfaceAsyncIterableSingleWithArgs, TestInterfaceAsyncIterableSingle)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(
+ TestInterfaceAsyncIterableSingleWithArgs, TestInterfaceAsyncIterableSingle)
+ NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mReturnLastCalledWith)
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
+NS_IMPL_ADDREF_INHERITED(TestInterfaceAsyncIterableSingleWithArgs,
+ TestInterfaceAsyncIterableSingle)
+NS_IMPL_RELEASE_INHERITED(TestInterfaceAsyncIterableSingleWithArgs,
+ TestInterfaceAsyncIterableSingle)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
+ TestInterfaceAsyncIterableSingleWithArgs)
+NS_INTERFACE_MAP_END_INHERITING(TestInterfaceAsyncIterableSingle)
+
+// static
+already_AddRefed<TestInterfaceAsyncIterableSingleWithArgs>
+TestInterfaceAsyncIterableSingleWithArgs::Constructor(
+ const GlobalObject& aGlobal, ErrorResult& aRv) {
+ nsCOMPtr<nsPIDOMWindowInner> window =
+ do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ RefPtr<TestInterfaceAsyncIterableSingleWithArgs> r =
+ new TestInterfaceAsyncIterableSingleWithArgs(window);
+ return r.forget();
+}
+
+JSObject* TestInterfaceAsyncIterableSingleWithArgs::WrapObject(
+ JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
+ return TestInterfaceAsyncIterableSingleWithArgs_Binding::Wrap(aCx, this,
+ aGivenProto);
+}
+
+void TestInterfaceAsyncIterableSingleWithArgs::InitAsyncIteratorData(
+ IteratorData& aData, Iterator::IteratorType aType,
+ const TestInterfaceAsyncIteratorOptions& aOptions, ErrorResult& aError) {
+ aData.mMultiplier = aOptions.mMultiplier;
+ aData.mBlockingPromises = aOptions.mBlockingPromises;
+ aData.mFailNextAfter = aOptions.mFailNextAfter;
+ aData.mThrowFromNext = aOptions.mThrowFromNext;
+ if (aOptions.mThrowFromReturn.WasPassed()) {
+ aData.mThrowFromReturn = &aOptions.mThrowFromReturn.Value();
+ }
+}
+
+already_AddRefed<Promise>
+TestInterfaceAsyncIterableSingleWithArgs::GetNextIterationResult(
+ Iterator* aIterator, ErrorResult& aRv) {
+ if (aIterator->Data().mThrowFromNext) {
+ AutoJSAPI jsapi;
+ MOZ_RELEASE_ASSERT(jsapi.Init(GetParentObject()));
+ JS_ReportErrorASCII(jsapi.cx(), "Throwing from next().");
+ aRv.MightThrowJSException();
+ aRv.StealExceptionFromJSContext(jsapi.cx());
+ return nullptr;
+ }
+
+ if (aIterator->Data().mIndex == aIterator->Data().mFailNextAfter) {
+ aRv.ThrowTypeError("Failed because we of 'failNextAfter'.");
+ return nullptr;
+ }
+ return TestInterfaceAsyncIterableSingle::GetNextIterationResult(
+ aIterator, aIterator->Data(), aRv);
+}
+
+already_AddRefed<Promise>
+TestInterfaceAsyncIterableSingleWithArgs::IteratorReturn(
+ JSContext* aCx, Iterator* aIterator, JS::Handle<JS::Value> aValue,
+ ErrorResult& aRv) {
+ ++mReturnCallCount;
+
+ if (RefPtr<TestThrowingCallback> throwFromReturn =
+ aIterator->Data().mThrowFromReturn) {
+ throwFromReturn->Call(aRv, nullptr, CallbackFunction::eRethrowExceptions);
+ return nullptr;
+ }
+
+ RefPtr<Promise> promise = Promise::Create(GetParentObject()->AsGlobal(), aRv);
+ if (NS_WARN_IF(aRv.Failed())) {
+ return nullptr;
+ }
+
+ mReturnLastCalledWith = aValue;
+ promise->MaybeResolve(JS::UndefinedHandleValue);
+ return promise.forget();
+}
+
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestInterfaceAsyncIterableSingleWithArgs.h b/dom/bindings/test/TestInterfaceAsyncIterableSingleWithArgs.h
new file mode 100644
index 0000000000..b9ef4853b8
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceAsyncIterableSingleWithArgs.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestInterfaceAsyncIterableSingleWithArgs_h
+#define mozilla_dom_TestInterfaceAsyncIterableSingleWithArgs_h
+
+#include "mozilla/dom/TestInterfaceAsyncIterableSingle.h"
+
+namespace mozilla::dom {
+
+struct TestInterfaceAsyncIteratorOptions;
+
+// Implementation of test binding for webidl iterable interfaces, using
+// primitives for value type
+class TestInterfaceAsyncIterableSingleWithArgs final
+ : public TestInterfaceAsyncIterableSingle {
+ public:
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
+ TestInterfaceAsyncIterableSingleWithArgs,
+ TestInterfaceAsyncIterableSingle)
+
+ using TestInterfaceAsyncIterableSingle::TestInterfaceAsyncIterableSingle;
+ virtual JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+ static already_AddRefed<TestInterfaceAsyncIterableSingleWithArgs> Constructor(
+ const GlobalObject& aGlobal, ErrorResult& rv);
+
+ using Iterator =
+ AsyncIterableIterator<TestInterfaceAsyncIterableSingleWithArgs>;
+
+ void InitAsyncIteratorData(IteratorData& aData, Iterator::IteratorType aType,
+ const TestInterfaceAsyncIteratorOptions& aOptions,
+ ErrorResult& aError);
+
+ already_AddRefed<Promise> GetNextIterationResult(
+ Iterator* aIterator, ErrorResult& aRv) MOZ_CAN_RUN_SCRIPT;
+ already_AddRefed<Promise> IteratorReturn(JSContext* aCx, Iterator* aIterator,
+ JS::Handle<JS::Value> aValue,
+ ErrorResult& aRv) MOZ_CAN_RUN_SCRIPT;
+
+ uint32_t ReturnCallCount() { return mReturnCallCount; }
+ void GetReturnLastCalledWith(JSContext* aCx,
+ JS::MutableHandle<JS::Value> aReturnCalledWith) {
+ aReturnCalledWith.set(mReturnLastCalledWith);
+ }
+
+ private:
+ ~TestInterfaceAsyncIterableSingleWithArgs() = default;
+
+ JS::Heap<JS::Value> mReturnLastCalledWith;
+ uint32_t mReturnCallCount = 0;
+};
+
+} // namespace mozilla::dom
+
+#endif // mozilla_dom_TestInterfaceAsyncIterableSingleWithArgs_h
diff --git a/dom/bindings/test/TestInterfaceIterableDouble.cpp b/dom/bindings/test/TestInterfaceIterableDouble.cpp
new file mode 100644
index 0000000000..8882518399
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceIterableDouble.cpp
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/dom/TestInterfaceIterableDouble.h"
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "nsPIDOMWindow.h"
+#include "mozilla/dom/BindingUtils.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceIterableDouble, mParent)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceIterableDouble)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceIterableDouble)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceIterableDouble)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+TestInterfaceIterableDouble::TestInterfaceIterableDouble(
+ nsPIDOMWindowInner* aParent)
+ : mParent(aParent) {
+ mValues.AppendElement(std::pair<nsString, nsString>(u"a"_ns, u"b"_ns));
+ mValues.AppendElement(std::pair<nsString, nsString>(u"c"_ns, u"d"_ns));
+ mValues.AppendElement(std::pair<nsString, nsString>(u"e"_ns, u"f"_ns));
+}
+
+// static
+already_AddRefed<TestInterfaceIterableDouble>
+TestInterfaceIterableDouble::Constructor(const GlobalObject& aGlobal,
+ ErrorResult& aRv) {
+ nsCOMPtr<nsPIDOMWindowInner> window =
+ do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ RefPtr<TestInterfaceIterableDouble> r =
+ new TestInterfaceIterableDouble(window);
+ return r.forget();
+}
+
+JSObject* TestInterfaceIterableDouble::WrapObject(
+ JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
+ return TestInterfaceIterableDouble_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+nsPIDOMWindowInner* TestInterfaceIterableDouble::GetParentObject() const {
+ return mParent;
+}
+
+size_t TestInterfaceIterableDouble::GetIterableLength() {
+ return mValues.Length();
+}
+
+nsAString& TestInterfaceIterableDouble::GetKeyAtIndex(uint32_t aIndex) {
+ MOZ_ASSERT(aIndex < mValues.Length());
+ return mValues.ElementAt(aIndex).first;
+}
+
+nsAString& TestInterfaceIterableDouble::GetValueAtIndex(uint32_t aIndex) {
+ MOZ_ASSERT(aIndex < mValues.Length());
+ return mValues.ElementAt(aIndex).second;
+}
+
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestInterfaceIterableDouble.h b/dom/bindings/test/TestInterfaceIterableDouble.h
new file mode 100644
index 0000000000..ba38b47e89
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceIterableDouble.h
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestInterfaceIterableDouble_h
+#define mozilla_dom_TestInterfaceIterableDouble_h
+
+#include "nsCOMPtr.h"
+#include "nsString.h"
+#include "nsTArray.h"
+#include "nsWrapperCache.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+
+class ErrorResult;
+
+namespace dom {
+
+class GlobalObject;
+
+// Implementation of test binding for webidl iterable interfaces, using
+// primitives for value type
+class TestInterfaceIterableDouble final : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(TestInterfaceIterableDouble)
+
+ explicit TestInterfaceIterableDouble(nsPIDOMWindowInner* aParent);
+ nsPIDOMWindowInner* GetParentObject() const;
+ virtual JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+ static already_AddRefed<TestInterfaceIterableDouble> Constructor(
+ const GlobalObject& aGlobal, ErrorResult& rv);
+
+ size_t GetIterableLength();
+ nsAString& GetKeyAtIndex(uint32_t aIndex);
+ nsAString& GetValueAtIndex(uint32_t aIndex);
+
+ private:
+ virtual ~TestInterfaceIterableDouble() = default;
+ nsCOMPtr<nsPIDOMWindowInner> mParent;
+ nsTArray<std::pair<nsString, nsString>> mValues;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TestInterfaceIterableDouble_h
diff --git a/dom/bindings/test/TestInterfaceIterableDoubleUnion.cpp b/dom/bindings/test/TestInterfaceIterableDoubleUnion.cpp
new file mode 100644
index 0000000000..56b968e549
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceIterableDoubleUnion.cpp
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/dom/TestInterfaceIterableDoubleUnion.h"
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "mozilla/dom/UnionTypes.h"
+#include "nsPIDOMWindow.h"
+#include "mozilla/dom/BindingUtils.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceIterableDoubleUnion, mParent)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceIterableDoubleUnion)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceIterableDoubleUnion)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceIterableDoubleUnion)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+TestInterfaceIterableDoubleUnion::TestInterfaceIterableDoubleUnion(
+ nsPIDOMWindowInner* aParent)
+ : mParent(aParent) {
+ OwningStringOrLong a;
+ a.SetAsLong() = 1;
+ mValues.AppendElement(std::pair<nsString, OwningStringOrLong>(u"long"_ns, a));
+ a.SetAsString() = u"a"_ns;
+ mValues.AppendElement(
+ std::pair<nsString, OwningStringOrLong>(u"string"_ns, a));
+}
+
+// static
+already_AddRefed<TestInterfaceIterableDoubleUnion>
+TestInterfaceIterableDoubleUnion::Constructor(const GlobalObject& aGlobal,
+ ErrorResult& aRv) {
+ nsCOMPtr<nsPIDOMWindowInner> window =
+ do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ RefPtr<TestInterfaceIterableDoubleUnion> r =
+ new TestInterfaceIterableDoubleUnion(window);
+ return r.forget();
+}
+
+JSObject* TestInterfaceIterableDoubleUnion::WrapObject(
+ JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
+ return TestInterfaceIterableDoubleUnion_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+nsPIDOMWindowInner* TestInterfaceIterableDoubleUnion::GetParentObject() const {
+ return mParent;
+}
+
+size_t TestInterfaceIterableDoubleUnion::GetIterableLength() {
+ return mValues.Length();
+}
+
+nsAString& TestInterfaceIterableDoubleUnion::GetKeyAtIndex(uint32_t aIndex) {
+ MOZ_ASSERT(aIndex < mValues.Length());
+ return mValues.ElementAt(aIndex).first;
+}
+
+OwningStringOrLong& TestInterfaceIterableDoubleUnion::GetValueAtIndex(
+ uint32_t aIndex) {
+ MOZ_ASSERT(aIndex < mValues.Length());
+ return mValues.ElementAt(aIndex).second;
+}
+
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestInterfaceIterableDoubleUnion.h b/dom/bindings/test/TestInterfaceIterableDoubleUnion.h
new file mode 100644
index 0000000000..d35744922e
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceIterableDoubleUnion.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestInterfaceIterableDoubleUnion_h
+#define mozilla_dom_TestInterfaceIterableDoubleUnion_h
+
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "nsCOMPtr.h"
+#include "nsWrapperCache.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+
+class ErrorResult;
+
+namespace dom {
+
+class GlobalObject;
+
+// Implementation of test binding for webidl iterable interfaces, using
+// primitives for value type
+class TestInterfaceIterableDoubleUnion final : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(TestInterfaceIterableDoubleUnion)
+
+ explicit TestInterfaceIterableDoubleUnion(nsPIDOMWindowInner* aParent);
+ nsPIDOMWindowInner* GetParentObject() const;
+ virtual JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+ static already_AddRefed<TestInterfaceIterableDoubleUnion> Constructor(
+ const GlobalObject& aGlobal, ErrorResult& rv);
+
+ size_t GetIterableLength();
+ nsAString& GetKeyAtIndex(uint32_t aIndex);
+ OwningStringOrLong& GetValueAtIndex(uint32_t aIndex);
+
+ private:
+ virtual ~TestInterfaceIterableDoubleUnion() = default;
+ nsCOMPtr<nsPIDOMWindowInner> mParent;
+ nsTArray<std::pair<nsString, OwningStringOrLong>> mValues;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TestInterfaceIterableDoubleUnion_h
diff --git a/dom/bindings/test/TestInterfaceIterableSingle.cpp b/dom/bindings/test/TestInterfaceIterableSingle.cpp
new file mode 100644
index 0000000000..4da02e9093
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceIterableSingle.cpp
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/dom/TestInterfaceIterableSingle.h"
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "nsPIDOMWindow.h"
+#include "mozilla/dom/BindingUtils.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceIterableSingle, mParent)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceIterableSingle)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceIterableSingle)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceIterableSingle)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+TestInterfaceIterableSingle::TestInterfaceIterableSingle(
+ nsPIDOMWindowInner* aParent)
+ : mParent(aParent) {
+ for (int i = 0; i < 3; ++i) {
+ mValues.AppendElement(i);
+ }
+}
+
+// static
+already_AddRefed<TestInterfaceIterableSingle>
+TestInterfaceIterableSingle::Constructor(const GlobalObject& aGlobal,
+ ErrorResult& aRv) {
+ nsCOMPtr<nsPIDOMWindowInner> window =
+ do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ RefPtr<TestInterfaceIterableSingle> r =
+ new TestInterfaceIterableSingle(window);
+ return r.forget();
+}
+
+JSObject* TestInterfaceIterableSingle::WrapObject(
+ JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
+ return TestInterfaceIterableSingle_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+nsPIDOMWindowInner* TestInterfaceIterableSingle::GetParentObject() const {
+ return mParent;
+}
+
+uint32_t TestInterfaceIterableSingle::Length() const {
+ return mValues.Length();
+}
+
+int32_t TestInterfaceIterableSingle::IndexedGetter(uint32_t aIndex,
+ bool& aFound) const {
+ if (aIndex >= mValues.Length()) {
+ aFound = false;
+ return 0;
+ }
+
+ aFound = true;
+ return mValues[aIndex];
+}
+
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestInterfaceIterableSingle.h b/dom/bindings/test/TestInterfaceIterableSingle.h
new file mode 100644
index 0000000000..68104d1d15
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceIterableSingle.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestInterfaceIterableSingle_h
+#define mozilla_dom_TestInterfaceIterableSingle_h
+
+#include "nsCOMPtr.h"
+#include "nsWrapperCache.h"
+#include "nsTArray.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+
+class ErrorResult;
+
+namespace dom {
+
+class GlobalObject;
+
+// Implementation of test binding for webidl iterable interfaces, using
+// primitives for value type
+class TestInterfaceIterableSingle final : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(TestInterfaceIterableSingle)
+
+ explicit TestInterfaceIterableSingle(nsPIDOMWindowInner* aParent);
+ nsPIDOMWindowInner* GetParentObject() const;
+ virtual JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+ static already_AddRefed<TestInterfaceIterableSingle> Constructor(
+ const GlobalObject& aGlobal, ErrorResult& rv);
+
+ uint32_t Length() const;
+ int32_t IndexedGetter(uint32_t aIndex, bool& aFound) const;
+
+ private:
+ virtual ~TestInterfaceIterableSingle() = default;
+ nsCOMPtr<nsPIDOMWindowInner> mParent;
+ nsTArray<int32_t> mValues;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TestInterfaceIterableSingle_h
diff --git a/dom/bindings/test/TestInterfaceJS.sys.mjs b/dom/bindings/test/TestInterfaceJS.sys.mjs
new file mode 100644
index 0000000000..53ce9d107d
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceJS.sys.mjs
@@ -0,0 +1,220 @@
+/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+/* global noSuchMethodExistsYo1, noSuchMethodExistsYo2, noSuchMethodExistsYo3 */
+
+export function TestInterfaceJS() {}
+
+TestInterfaceJS.prototype = {
+ QueryInterface: ChromeUtils.generateQI([
+ "nsIDOMGlobalPropertyInitializer",
+ "mozITestInterfaceJS",
+ ]),
+
+ init(win) {
+ this._win = win;
+ },
+
+ __init(anyArg, objectArg, dictionaryArg) {
+ this._anyAttr = undefined;
+ this._objectAttr = null;
+ this._anyArg = anyArg;
+ this._objectArg = objectArg;
+ this._dictionaryArg = dictionaryArg;
+ },
+
+ get anyArg() {
+ return this._anyArg;
+ },
+ get objectArg() {
+ return this._objectArg;
+ },
+ getDictionaryArg() {
+ return this._dictionaryArg;
+ },
+ get anyAttr() {
+ return this._anyAttr;
+ },
+ set anyAttr(val) {
+ this._anyAttr = val;
+ },
+ get objectAttr() {
+ return this._objectAttr;
+ },
+ set objectAttr(val) {
+ this._objectAttr = val;
+ },
+ getDictionaryAttr() {
+ return this._dictionaryAttr;
+ },
+ setDictionaryAttr(val) {
+ this._dictionaryAttr = val;
+ },
+ pingPongAny(any) {
+ return any;
+ },
+ pingPongObject(obj) {
+ return obj;
+ },
+ pingPongObjectOrString(objectOrString) {
+ return objectOrString;
+ },
+ pingPongDictionary(dict) {
+ return dict;
+ },
+ pingPongDictionaryOrLong(dictOrLong) {
+ return dictOrLong.anyMember || dictOrLong;
+ },
+ pingPongRecord(rec) {
+ return JSON.stringify(rec);
+ },
+ objectSequenceLength(seq) {
+ return seq.length;
+ },
+ anySequenceLength(seq) {
+ return seq.length;
+ },
+
+ getCallerPrincipal() {
+ return Cu.getWebIDLCallerPrincipal().origin;
+ },
+
+ convertSVS(svs) {
+ return svs;
+ },
+
+ pingPongUnion(x) {
+ return x;
+ },
+ pingPongUnionContainingNull(x) {
+ return x;
+ },
+ pingPongNullableUnion(x) {
+ return x;
+ },
+ returnBadUnion(x) {
+ return 3;
+ },
+
+ testSequenceOverload(arg) {},
+ testSequenceUnion(arg) {},
+
+ testThrowError() {
+ throw new this._win.Error("We are an Error");
+ },
+
+ testThrowDOMException() {
+ throw new this._win.DOMException(
+ "We are a DOMException",
+ "NotSupportedError"
+ );
+ },
+
+ testThrowTypeError() {
+ throw new this._win.TypeError("We are a TypeError");
+ },
+
+ testThrowNsresult() {
+ // This is explicitly testing preservation of raw thrown Crs in XPCJS
+ // eslint-disable-next-line mozilla/no-throw-cr-literal
+ throw Cr.NS_BINDING_ABORTED;
+ },
+
+ testThrowNsresultFromNative(x) {
+ // We want to throw an exception that we generate from an nsresult thrown
+ // by a C++ component.
+ Services.io.notImplemented();
+ },
+
+ testThrowCallbackError(callback) {
+ callback();
+ },
+
+ testThrowXraySelfHosted() {
+ this._win.Array.prototype.forEach();
+ },
+
+ testThrowSelfHosted() {
+ Array.prototype.forEach();
+ },
+
+ testPromiseWithThrowingChromePromiseInit() {
+ return new this._win.Promise(function () {
+ noSuchMethodExistsYo1();
+ });
+ },
+
+ testPromiseWithThrowingContentPromiseInit(func) {
+ return new this._win.Promise(func);
+ },
+
+ testPromiseWithDOMExceptionThrowingPromiseInit() {
+ return new this._win.Promise(() => {
+ throw new this._win.DOMException(
+ "We are a second DOMException",
+ "NotFoundError"
+ );
+ });
+ },
+
+ testPromiseWithThrowingChromeThenFunction() {
+ return this._win.Promise.resolve(5).then(function () {
+ noSuchMethodExistsYo2();
+ });
+ },
+
+ testPromiseWithThrowingContentThenFunction(func) {
+ return this._win.Promise.resolve(10).then(func);
+ },
+
+ testPromiseWithDOMExceptionThrowingThenFunction() {
+ return this._win.Promise.resolve(5).then(() => {
+ throw new this._win.DOMException(
+ "We are a third DOMException",
+ "NetworkError"
+ );
+ });
+ },
+
+ testPromiseWithThrowingChromeThenable() {
+ var thenable = {
+ then() {
+ noSuchMethodExistsYo3();
+ },
+ };
+ return new this._win.Promise(function (resolve) {
+ resolve(thenable);
+ });
+ },
+
+ testPromiseWithThrowingContentThenable(thenable) {
+ // Waive Xrays on the thenable, because we're calling resolve() in the
+ // chrome compartment, so that's the compartment the "then" property get
+ // will happen in, and if we leave the Xray in place the function-valued
+ // property won't return the function.
+ return this._win.Promise.resolve(Cu.waiveXrays(thenable));
+ },
+
+ testPromiseWithDOMExceptionThrowingThenable() {
+ var thenable = {
+ then: () => {
+ throw new this._win.DOMException(
+ "We are a fourth DOMException",
+ "TypeMismatchError"
+ );
+ },
+ };
+ return new this._win.Promise(function (resolve) {
+ resolve(thenable);
+ });
+ },
+
+ get onsomething() {
+ return this.__DOM_IMPL__.getEventHandler("onsomething");
+ },
+
+ set onsomething(val) {
+ this.__DOM_IMPL__.setEventHandler("onsomething", val);
+ },
+};
diff --git a/dom/bindings/test/TestInterfaceLength.cpp b/dom/bindings/test/TestInterfaceLength.cpp
new file mode 100644
index 0000000000..cbb2ffa5c6
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceLength.cpp
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#include "mozilla/dom/TestInterfaceLength.h"
+#include "mozilla/dom/TestFunctionsBinding.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(TestInterfaceLength)
+
+JSObject* TestInterfaceLength::WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) {
+ return TestInterfaceLength_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+already_AddRefed<TestInterfaceLength> TestInterfaceLength::Constructor(
+ const GlobalObject& aGlobalObject, const bool aArg) {
+ return MakeAndAddRef<TestInterfaceLength>();
+}
+
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestInterfaceLength.h b/dom/bindings/test/TestInterfaceLength.h
new file mode 100644
index 0000000000..989333bbf0
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceLength.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestInterfaceLength_h
+#define mozilla_dom_TestInterfaceLength_h
+
+#include "js/TypeDecls.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/dom/BindingDeclarations.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsWrapperCache.h"
+
+namespace mozilla::dom {
+
+class TestInterfaceLength final : public nsWrapperCache {
+ public:
+ NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(TestInterfaceLength)
+ NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(TestInterfaceLength)
+
+ public:
+ TestInterfaceLength() = default;
+
+ static already_AddRefed<TestInterfaceLength> Constructor(
+ const GlobalObject& aGlobalObject, const bool aArg);
+
+ protected:
+ ~TestInterfaceLength() = default;
+
+ public:
+ nsISupports* GetParentObject() const { return nullptr; }
+ JSObject* WrapObject(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
+};
+
+} // namespace mozilla::dom
+
+#endif // mozilla_dom_TestInterfaceLength_h
diff --git a/dom/bindings/test/TestInterfaceMaplike.cpp b/dom/bindings/test/TestInterfaceMaplike.cpp
new file mode 100644
index 0000000000..ba8ccf7279
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceMaplike.cpp
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/dom/TestInterfaceMaplike.h"
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "nsPIDOMWindow.h"
+#include "mozilla/dom/BindingUtils.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceMaplike, mParent)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceMaplike)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceMaplike)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceMaplike)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+TestInterfaceMaplike::TestInterfaceMaplike(nsPIDOMWindowInner* aParent)
+ : mParent(aParent) {}
+
+// static
+already_AddRefed<TestInterfaceMaplike> TestInterfaceMaplike::Constructor(
+ const GlobalObject& aGlobal, ErrorResult& aRv) {
+ nsCOMPtr<nsPIDOMWindowInner> window =
+ do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ RefPtr<TestInterfaceMaplike> r = new TestInterfaceMaplike(window);
+ return r.forget();
+}
+
+JSObject* TestInterfaceMaplike::WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) {
+ return TestInterfaceMaplike_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+nsPIDOMWindowInner* TestInterfaceMaplike::GetParentObject() const {
+ return mParent;
+}
+
+void TestInterfaceMaplike::SetInternal(const nsAString& aKey, int32_t aValue) {
+ ErrorResult rv;
+ TestInterfaceMaplike_Binding::MaplikeHelpers::Set(this, aKey, aValue, rv);
+}
+
+void TestInterfaceMaplike::ClearInternal() {
+ ErrorResult rv;
+ TestInterfaceMaplike_Binding::MaplikeHelpers::Clear(this, rv);
+}
+
+bool TestInterfaceMaplike::DeleteInternal(const nsAString& aKey) {
+ ErrorResult rv;
+ return TestInterfaceMaplike_Binding::MaplikeHelpers::Delete(this, aKey, rv);
+}
+
+bool TestInterfaceMaplike::HasInternal(const nsAString& aKey) {
+ ErrorResult rv;
+ return TestInterfaceMaplike_Binding::MaplikeHelpers::Has(this, aKey, rv);
+}
+
+int32_t TestInterfaceMaplike::GetInternal(const nsAString& aKey,
+ ErrorResult& aRv) {
+ return TestInterfaceMaplike_Binding::MaplikeHelpers::Get(this, aKey, aRv);
+}
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestInterfaceMaplike.h b/dom/bindings/test/TestInterfaceMaplike.h
new file mode 100644
index 0000000000..e82f290d17
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceMaplike.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestInterfaceMaplike_h
+#define mozilla_dom_TestInterfaceMaplike_h
+
+#include "nsWrapperCache.h"
+#include "nsCOMPtr.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+
+class ErrorResult;
+
+namespace dom {
+
+class GlobalObject;
+
+// Implementation of test binding for webidl maplike interfaces, using
+// primitives for key and value types.
+class TestInterfaceMaplike final : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(TestInterfaceMaplike)
+
+ explicit TestInterfaceMaplike(nsPIDOMWindowInner* aParent);
+ nsPIDOMWindowInner* GetParentObject() const;
+ virtual JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+ static already_AddRefed<TestInterfaceMaplike> Constructor(
+ const GlobalObject& aGlobal, ErrorResult& rv);
+
+ // External access for testing internal convenience functions.
+ void SetInternal(const nsAString& aKey, int32_t aValue);
+ void ClearInternal();
+ bool DeleteInternal(const nsAString& aKey);
+ bool HasInternal(const nsAString& aKey);
+ int32_t GetInternal(const nsAString& aKey, ErrorResult& aRv);
+
+ private:
+ virtual ~TestInterfaceMaplike() = default;
+ nsCOMPtr<nsPIDOMWindowInner> mParent;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TestInterfaceMaplike_h
diff --git a/dom/bindings/test/TestInterfaceMaplikeJSObject.cpp b/dom/bindings/test/TestInterfaceMaplikeJSObject.cpp
new file mode 100644
index 0000000000..e9fb50e4b6
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceMaplikeJSObject.cpp
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/dom/TestInterfaceMaplikeJSObject.h"
+#include "mozilla/dom/TestInterfaceMaplike.h"
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "nsPIDOMWindow.h"
+#include "mozilla/dom/BindingUtils.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceMaplikeJSObject, mParent)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceMaplikeJSObject)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceMaplikeJSObject)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceMaplikeJSObject)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+TestInterfaceMaplikeJSObject::TestInterfaceMaplikeJSObject(
+ nsPIDOMWindowInner* aParent)
+ : mParent(aParent) {}
+
+// static
+already_AddRefed<TestInterfaceMaplikeJSObject>
+TestInterfaceMaplikeJSObject::Constructor(const GlobalObject& aGlobal,
+ ErrorResult& aRv) {
+ nsCOMPtr<nsPIDOMWindowInner> window =
+ do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ RefPtr<TestInterfaceMaplikeJSObject> r =
+ new TestInterfaceMaplikeJSObject(window);
+ return r.forget();
+}
+
+JSObject* TestInterfaceMaplikeJSObject::WrapObject(
+ JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
+ return TestInterfaceMaplikeJSObject_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+nsPIDOMWindowInner* TestInterfaceMaplikeJSObject::GetParentObject() const {
+ return mParent;
+}
+
+void TestInterfaceMaplikeJSObject::SetInternal(JSContext* aCx,
+ const nsAString& aKey,
+ JS::Handle<JSObject*> aObject) {
+ ErrorResult rv;
+ TestInterfaceMaplikeJSObject_Binding::MaplikeHelpers::Set(this, aKey, aObject,
+ rv);
+}
+
+void TestInterfaceMaplikeJSObject::ClearInternal() {
+ ErrorResult rv;
+ TestInterfaceMaplikeJSObject_Binding::MaplikeHelpers::Clear(this, rv);
+}
+
+bool TestInterfaceMaplikeJSObject::DeleteInternal(const nsAString& aKey) {
+ ErrorResult rv;
+ return TestInterfaceMaplikeJSObject_Binding::MaplikeHelpers::Delete(this,
+ aKey, rv);
+}
+
+bool TestInterfaceMaplikeJSObject::HasInternal(const nsAString& aKey) {
+ ErrorResult rv;
+ return TestInterfaceMaplikeJSObject_Binding::MaplikeHelpers::Has(this, aKey,
+ rv);
+}
+
+void TestInterfaceMaplikeJSObject::GetInternal(
+ JSContext* aCx, const nsAString& aKey, JS::MutableHandle<JSObject*> aRetVal,
+ ErrorResult& aRv) {
+ TestInterfaceMaplikeJSObject_Binding::MaplikeHelpers::Get(this, aCx, aKey,
+ aRetVal, aRv);
+}
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestInterfaceMaplikeJSObject.h b/dom/bindings/test/TestInterfaceMaplikeJSObject.h
new file mode 100644
index 0000000000..00feda7796
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceMaplikeJSObject.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestInterfaceMaplikeJSObject_h
+#define mozilla_dom_TestInterfaceMaplikeJSObject_h
+
+#include "nsWrapperCache.h"
+#include "nsCOMPtr.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+
+class ErrorResult;
+
+namespace dom {
+
+class GlobalObject;
+
+// Implementation of test binding for webidl maplike interfaces, using
+// primitives for key types and objects for value types.
+class TestInterfaceMaplikeJSObject final : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(TestInterfaceMaplikeJSObject)
+
+ explicit TestInterfaceMaplikeJSObject(nsPIDOMWindowInner* aParent);
+ nsPIDOMWindowInner* GetParentObject() const;
+ virtual JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+ static already_AddRefed<TestInterfaceMaplikeJSObject> Constructor(
+ const GlobalObject& aGlobal, ErrorResult& rv);
+
+ // External access for testing internal convenience functions.
+ void SetInternal(JSContext* aCx, const nsAString& aKey,
+ JS::Handle<JSObject*> aObject);
+ void ClearInternal();
+ bool DeleteInternal(const nsAString& aKey);
+ bool HasInternal(const nsAString& aKey);
+ void GetInternal(JSContext* aCx, const nsAString& aKey,
+ JS::MutableHandle<JSObject*> aRetVal, ErrorResult& aRv);
+
+ private:
+ virtual ~TestInterfaceMaplikeJSObject() = default;
+ nsCOMPtr<nsPIDOMWindowInner> mParent;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TestInterfaceMaplikeJSObject_h
diff --git a/dom/bindings/test/TestInterfaceMaplikeObject.cpp b/dom/bindings/test/TestInterfaceMaplikeObject.cpp
new file mode 100644
index 0000000000..b05e33df6b
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceMaplikeObject.cpp
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/dom/TestInterfaceMaplikeObject.h"
+#include "mozilla/dom/TestInterfaceMaplike.h"
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "nsPIDOMWindow.h"
+#include "mozilla/dom/BindingUtils.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceMaplikeObject, mParent)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceMaplikeObject)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceMaplikeObject)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceMaplikeObject)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+TestInterfaceMaplikeObject::TestInterfaceMaplikeObject(
+ nsPIDOMWindowInner* aParent)
+ : mParent(aParent) {}
+
+// static
+already_AddRefed<TestInterfaceMaplikeObject>
+TestInterfaceMaplikeObject::Constructor(const GlobalObject& aGlobal,
+ ErrorResult& aRv) {
+ nsCOMPtr<nsPIDOMWindowInner> window =
+ do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ RefPtr<TestInterfaceMaplikeObject> r = new TestInterfaceMaplikeObject(window);
+ return r.forget();
+}
+
+JSObject* TestInterfaceMaplikeObject::WrapObject(
+ JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
+ return TestInterfaceMaplikeObject_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+nsPIDOMWindowInner* TestInterfaceMaplikeObject::GetParentObject() const {
+ return mParent;
+}
+
+void TestInterfaceMaplikeObject::SetInternal(const nsAString& aKey) {
+ RefPtr<TestInterfaceMaplike> p(new TestInterfaceMaplike(mParent));
+ ErrorResult rv;
+ TestInterfaceMaplikeObject_Binding::MaplikeHelpers::Set(this, aKey, *p, rv);
+}
+
+void TestInterfaceMaplikeObject::ClearInternal() {
+ ErrorResult rv;
+ TestInterfaceMaplikeObject_Binding::MaplikeHelpers::Clear(this, rv);
+}
+
+bool TestInterfaceMaplikeObject::DeleteInternal(const nsAString& aKey) {
+ ErrorResult rv;
+ return TestInterfaceMaplikeObject_Binding::MaplikeHelpers::Delete(this, aKey,
+ rv);
+}
+
+bool TestInterfaceMaplikeObject::HasInternal(const nsAString& aKey) {
+ ErrorResult rv;
+ return TestInterfaceMaplikeObject_Binding::MaplikeHelpers::Has(this, aKey,
+ rv);
+}
+
+already_AddRefed<TestInterfaceMaplike> TestInterfaceMaplikeObject::GetInternal(
+ const nsAString& aKey, ErrorResult& aRv) {
+ return TestInterfaceMaplikeObject_Binding::MaplikeHelpers::Get(this, aKey,
+ aRv);
+}
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestInterfaceMaplikeObject.h b/dom/bindings/test/TestInterfaceMaplikeObject.h
new file mode 100644
index 0000000000..894447cc41
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceMaplikeObject.h
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestInterfaceMaplikeObject_h
+#define mozilla_dom_TestInterfaceMaplikeObject_h
+
+#include "nsWrapperCache.h"
+#include "nsCOMPtr.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+
+class ErrorResult;
+
+namespace dom {
+
+class GlobalObject;
+class TestInterfaceMaplike;
+
+// Implementation of test binding for webidl maplike interfaces, using
+// primitives for key types and objects for value types.
+class TestInterfaceMaplikeObject final : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(TestInterfaceMaplikeObject)
+
+ explicit TestInterfaceMaplikeObject(nsPIDOMWindowInner* aParent);
+ nsPIDOMWindowInner* GetParentObject() const;
+ virtual JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+ static already_AddRefed<TestInterfaceMaplikeObject> Constructor(
+ const GlobalObject& aGlobal, ErrorResult& rv);
+
+ // External access for testing internal convenience functions.
+ void SetInternal(const nsAString& aKey);
+ void ClearInternal();
+ bool DeleteInternal(const nsAString& aKey);
+ bool HasInternal(const nsAString& aKey);
+ already_AddRefed<TestInterfaceMaplike> GetInternal(const nsAString& aKey,
+ ErrorResult& aRv);
+
+ private:
+ virtual ~TestInterfaceMaplikeObject() = default;
+ nsCOMPtr<nsPIDOMWindowInner> mParent;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TestInterfaceMaplikeObject_h
diff --git a/dom/bindings/test/TestInterfaceObservableArray.cpp b/dom/bindings/test/TestInterfaceObservableArray.cpp
new file mode 100644
index 0000000000..cb8d532eb8
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceObservableArray.cpp
@@ -0,0 +1,225 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/dom/TestInterfaceObservableArray.h"
+#include "mozilla/dom/TestInterfaceObservableArrayBinding.h"
+#include "nsPIDOMWindow.h"
+#include "mozilla/dom/BindingUtils.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceObservableArray, mParent,
+ mSetBooleanCallback,
+ mDeleteBooleanCallback,
+ mSetObjectCallback, mDeleteObjectCallback,
+ mSetInterfaceCallback,
+ mDeleteInterfaceCallback)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceObservableArray)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceObservableArray)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceObservableArray)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+TestInterfaceObservableArray::TestInterfaceObservableArray(
+ nsPIDOMWindowInner* aParent, const ObservableArrayCallbacks& aCallbacks)
+ : mParent(aParent) {
+ if (aCallbacks.mSetBooleanCallback.WasPassed()) {
+ mSetBooleanCallback = &aCallbacks.mSetBooleanCallback.Value();
+ }
+ if (aCallbacks.mDeleteBooleanCallback.WasPassed()) {
+ mDeleteBooleanCallback = &aCallbacks.mDeleteBooleanCallback.Value();
+ }
+ if (aCallbacks.mSetObjectCallback.WasPassed()) {
+ mSetObjectCallback = &aCallbacks.mSetObjectCallback.Value();
+ }
+ if (aCallbacks.mDeleteObjectCallback.WasPassed()) {
+ mDeleteObjectCallback = &aCallbacks.mDeleteObjectCallback.Value();
+ }
+ if (aCallbacks.mSetInterfaceCallback.WasPassed()) {
+ mSetInterfaceCallback = &aCallbacks.mSetInterfaceCallback.Value();
+ }
+ if (aCallbacks.mDeleteInterfaceCallback.WasPassed()) {
+ mDeleteInterfaceCallback = &aCallbacks.mDeleteInterfaceCallback.Value();
+ }
+}
+
+// static
+already_AddRefed<TestInterfaceObservableArray>
+TestInterfaceObservableArray::Constructor(
+ const GlobalObject& aGlobal, const ObservableArrayCallbacks& aCallbacks,
+ ErrorResult& aRv) {
+ nsCOMPtr<nsPIDOMWindowInner> window =
+ do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ RefPtr<TestInterfaceObservableArray> r =
+ new TestInterfaceObservableArray(window, aCallbacks);
+ return r.forget();
+}
+
+JSObject* TestInterfaceObservableArray::WrapObject(
+ JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
+ return TestInterfaceObservableArray_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+nsPIDOMWindowInner* TestInterfaceObservableArray::GetParentObject() const {
+ return mParent;
+}
+
+void TestInterfaceObservableArray::OnSetObservableArrayObject(
+ JSContext* aCx, JS::Handle<JSObject*> aValue, uint32_t aIndex,
+ ErrorResult& aRv) {
+ if (mSetObjectCallback) {
+ MOZ_KnownLive(mSetObjectCallback)
+ ->Call(aValue, aIndex, aRv, "OnSetObservableArrayObject",
+ CallbackFunction::eRethrowExceptions);
+ }
+}
+
+void TestInterfaceObservableArray::OnDeleteObservableArrayObject(
+ JSContext* aCx, JS::Handle<JSObject*> aValue, uint32_t aIndex,
+ ErrorResult& aRv) {
+ if (mDeleteObjectCallback) {
+ MOZ_KnownLive(mDeleteObjectCallback)
+ ->Call(aValue, aIndex, aRv, "OnDeleteObservableArrayObject",
+ CallbackFunction::eRethrowExceptions);
+ }
+}
+
+void TestInterfaceObservableArray::OnSetObservableArrayBoolean(
+ bool aValue, uint32_t aIndex, ErrorResult& aRv) {
+ if (mSetBooleanCallback) {
+ MOZ_KnownLive(mSetBooleanCallback)
+ ->Call(aValue, aIndex, aRv, "OnSetObservableArrayBoolean",
+ CallbackFunction::eRethrowExceptions);
+ }
+}
+
+void TestInterfaceObservableArray::OnDeleteObservableArrayBoolean(
+ bool aValue, uint32_t aIndex, ErrorResult& aRv) {
+ if (mDeleteBooleanCallback) {
+ MOZ_KnownLive(mDeleteBooleanCallback)
+ ->Call(aValue, aIndex, aRv, "OnDeleteObservableArrayBoolean",
+ CallbackFunction::eRethrowExceptions);
+ }
+}
+
+void TestInterfaceObservableArray::OnSetObservableArrayInterface(
+ TestInterfaceObservableArray* aValue, uint32_t aIndex, ErrorResult& aRv) {
+ if (mSetInterfaceCallback && aValue) {
+ MOZ_KnownLive(mSetInterfaceCallback)
+ ->Call(*aValue, aIndex, aRv, "OnSetObservableArrayInterface",
+ CallbackFunction::eRethrowExceptions);
+ }
+}
+
+void TestInterfaceObservableArray::OnDeleteObservableArrayInterface(
+ TestInterfaceObservableArray* aValue, uint32_t aIndex, ErrorResult& aRv) {
+ if (mDeleteInterfaceCallback && aValue) {
+ MOZ_KnownLive(mDeleteInterfaceCallback)
+ ->Call(*aValue, aIndex, aRv, "OnDeleteObservableArrayInterface",
+ CallbackFunction::eRethrowExceptions);
+ }
+}
+
+bool TestInterfaceObservableArray::BooleanElementAtInternal(uint32_t aIndex,
+ ErrorResult& aRv) {
+ return TestInterfaceObservableArray_Binding::ObservableArrayBooleanHelpers::
+ ElementAt(this, aIndex, aRv);
+}
+
+void TestInterfaceObservableArray::ObjectElementAtInternal(
+ JSContext* aCx, uint32_t aIndex, JS::MutableHandle<JSObject*> aValue,
+ ErrorResult& aRv) {
+ TestInterfaceObservableArray_Binding::ObservableArrayObjectHelpers::ElementAt(
+ this, aCx, aIndex, aValue, aRv);
+}
+
+already_AddRefed<TestInterfaceObservableArray>
+TestInterfaceObservableArray::InterfaceElementAtInternal(uint32_t aIndex,
+ ErrorResult& aRv) {
+ return TestInterfaceObservableArray_Binding::ObservableArrayInterfaceHelpers::
+ ElementAt(this, aIndex, aRv);
+}
+
+void TestInterfaceObservableArray::BooleanReplaceElementAtInternal(
+ uint32_t aIndex, bool aValue, ErrorResult& aRv) {
+ TestInterfaceObservableArray_Binding::ObservableArrayBooleanHelpers::
+ ReplaceElementAt(this, aIndex, aValue, aRv);
+}
+
+void TestInterfaceObservableArray::ObjectReplaceElementAtInternal(
+ JSContext* aCx, uint32_t aIndex, JS::Handle<JSObject*> aValue,
+ ErrorResult& aRv) {
+ TestInterfaceObservableArray_Binding::ObservableArrayObjectHelpers::
+ ReplaceElementAt(this, aIndex, aValue, aRv);
+}
+
+void TestInterfaceObservableArray::InterfaceReplaceElementAtInternal(
+ uint32_t aIndex, TestInterfaceObservableArray& aValue, ErrorResult& aRv) {
+ TestInterfaceObservableArray_Binding::ObservableArrayInterfaceHelpers::
+ ReplaceElementAt(this, aIndex, aValue, aRv);
+}
+
+void TestInterfaceObservableArray::BooleanAppendElementInternal(
+ bool aValue, ErrorResult& aRv) {
+ TestInterfaceObservableArray_Binding::ObservableArrayBooleanHelpers::
+ AppendElement(this, aValue, aRv);
+}
+
+void TestInterfaceObservableArray::ObjectAppendElementInternal(
+ JSContext* aCx, JS::Handle<JSObject*> aValue, ErrorResult& aRv) {
+ TestInterfaceObservableArray_Binding::ObservableArrayObjectHelpers::
+ AppendElement(this, aValue, aRv);
+}
+
+void TestInterfaceObservableArray::InterfaceAppendElementInternal(
+ TestInterfaceObservableArray& aValue, ErrorResult& aRv) {
+ TestInterfaceObservableArray_Binding::ObservableArrayInterfaceHelpers::
+ AppendElement(this, aValue, aRv);
+}
+
+void TestInterfaceObservableArray::BooleanRemoveLastElementInternal(
+ ErrorResult& aRv) {
+ TestInterfaceObservableArray_Binding::ObservableArrayBooleanHelpers::
+ RemoveLastElement(this, aRv);
+}
+
+void TestInterfaceObservableArray::ObjectRemoveLastElementInternal(
+ ErrorResult& aRv) {
+ TestInterfaceObservableArray_Binding::ObservableArrayObjectHelpers::
+ RemoveLastElement(this, aRv);
+}
+
+void TestInterfaceObservableArray::InterfaceRemoveLastElementInternal(
+ ErrorResult& aRv) {
+ TestInterfaceObservableArray_Binding::ObservableArrayInterfaceHelpers::
+ RemoveLastElement(this, aRv);
+}
+
+uint32_t TestInterfaceObservableArray::BooleanLengthInternal(ErrorResult& aRv) {
+ return TestInterfaceObservableArray_Binding::ObservableArrayBooleanHelpers::
+ Length(this, aRv);
+}
+
+uint32_t TestInterfaceObservableArray::ObjectLengthInternal(ErrorResult& aRv) {
+ return TestInterfaceObservableArray_Binding::ObservableArrayObjectHelpers::
+ Length(this, aRv);
+}
+
+uint32_t TestInterfaceObservableArray::InterfaceLengthInternal(
+ ErrorResult& aRv) {
+ return TestInterfaceObservableArray_Binding::ObservableArrayInterfaceHelpers::
+ Length(this, aRv);
+}
+
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestInterfaceObservableArray.h b/dom/bindings/test/TestInterfaceObservableArray.h
new file mode 100644
index 0000000000..3329663ac6
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceObservableArray.h
@@ -0,0 +1,115 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestInterfaceObservableArray_h
+#define mozilla_dom_TestInterfaceObservableArray_h
+
+#include "nsCOMPtr.h"
+#include "nsWrapperCache.h"
+#include "nsTArray.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+
+class ErrorResult;
+
+namespace dom {
+
+class GlobalObject;
+class SetDeleteBooleanCallback;
+class SetDeleteInterfaceCallback;
+class SetDeleteObjectCallback;
+struct ObservableArrayCallbacks;
+
+// Implementation of test binding for webidl ObservableArray type, using
+// primitives for value type
+class TestInterfaceObservableArray final : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(TestInterfaceObservableArray)
+
+ nsPIDOMWindowInner* GetParentObject() const;
+ virtual JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+ static already_AddRefed<TestInterfaceObservableArray> Constructor(
+ const GlobalObject& aGlobal, const ObservableArrayCallbacks& aCallbacks,
+ ErrorResult& rv);
+
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY
+ void OnSetObservableArrayObject(JSContext* aCx, JS::Handle<JSObject*> aValue,
+ uint32_t aIndex, ErrorResult& aRv);
+
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY
+ void OnDeleteObservableArrayObject(JSContext* aCx,
+ JS::Handle<JSObject*> aValue,
+ uint32_t aIndex, ErrorResult& aRv);
+
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY
+ void OnSetObservableArrayBoolean(bool aValue, uint32_t aIndex,
+ ErrorResult& aRv);
+
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY
+ void OnDeleteObservableArrayBoolean(bool aValue, uint32_t aIndex,
+ ErrorResult& aRv);
+
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY
+ void OnSetObservableArrayInterface(TestInterfaceObservableArray* aValue,
+ uint32_t aIndex, ErrorResult& aRv);
+
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY
+ void OnDeleteObservableArrayInterface(TestInterfaceObservableArray* aValue,
+ uint32_t aIndex, ErrorResult& aRv);
+
+ bool BooleanElementAtInternal(uint32_t aIndex, ErrorResult& aRv);
+ void ObjectElementAtInternal(JSContext* aCx, uint32_t aIndex,
+ JS::MutableHandle<JSObject*> aValue,
+ ErrorResult& aRv);
+ already_AddRefed<TestInterfaceObservableArray> InterfaceElementAtInternal(
+ uint32_t aIndex, ErrorResult& aRv);
+
+ void BooleanReplaceElementAtInternal(uint32_t aIndex, bool aValue,
+ ErrorResult& aRv);
+ void ObjectReplaceElementAtInternal(JSContext* aCx, uint32_t aIndex,
+ JS::Handle<JSObject*> aValue,
+ ErrorResult& aRv);
+ void InterfaceReplaceElementAtInternal(uint32_t aIndex,
+ TestInterfaceObservableArray& aValue,
+ ErrorResult& aRv);
+
+ void BooleanAppendElementInternal(bool aValue, ErrorResult& aRv);
+ void ObjectAppendElementInternal(JSContext* aCx, JS::Handle<JSObject*> aValue,
+ ErrorResult& aRv);
+ void InterfaceAppendElementInternal(TestInterfaceObservableArray& aValue,
+ ErrorResult& aRv);
+
+ void BooleanRemoveLastElementInternal(ErrorResult& aRv);
+ void ObjectRemoveLastElementInternal(ErrorResult& aRv);
+ void InterfaceRemoveLastElementInternal(ErrorResult& aRv);
+
+ uint32_t BooleanLengthInternal(ErrorResult& aRv);
+ uint32_t ObjectLengthInternal(ErrorResult& aRv);
+ uint32_t InterfaceLengthInternal(ErrorResult& aRv);
+
+ private:
+ explicit TestInterfaceObservableArray(
+ nsPIDOMWindowInner* aParent, const ObservableArrayCallbacks& aCallbacks);
+ virtual ~TestInterfaceObservableArray() = default;
+
+ nsCOMPtr<nsPIDOMWindowInner> mParent;
+ RefPtr<SetDeleteBooleanCallback> mSetBooleanCallback;
+ RefPtr<SetDeleteBooleanCallback> mDeleteBooleanCallback;
+ RefPtr<SetDeleteObjectCallback> mSetObjectCallback;
+ RefPtr<SetDeleteObjectCallback> mDeleteObjectCallback;
+ RefPtr<SetDeleteInterfaceCallback> mSetInterfaceCallback;
+ RefPtr<SetDeleteInterfaceCallback> mDeleteInterfaceCallback;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TestInterfaceObservableArray_h
diff --git a/dom/bindings/test/TestInterfaceSetlike.cpp b/dom/bindings/test/TestInterfaceSetlike.cpp
new file mode 100644
index 0000000000..ac973d1c23
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceSetlike.cpp
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/dom/TestInterfaceSetlike.h"
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "nsPIDOMWindow.h"
+#include "mozilla/dom/BindingUtils.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceSetlike, mParent)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceSetlike)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceSetlike)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceSetlike)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+TestInterfaceSetlike::TestInterfaceSetlike(JSContext* aCx,
+ nsPIDOMWindowInner* aParent)
+ : mParent(aParent) {}
+
+// static
+already_AddRefed<TestInterfaceSetlike> TestInterfaceSetlike::Constructor(
+ const GlobalObject& aGlobal, ErrorResult& aRv) {
+ nsCOMPtr<nsPIDOMWindowInner> window =
+ do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ RefPtr<TestInterfaceSetlike> r = new TestInterfaceSetlike(nullptr, window);
+ return r.forget();
+}
+
+JSObject* TestInterfaceSetlike::WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) {
+ return TestInterfaceSetlike_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+nsPIDOMWindowInner* TestInterfaceSetlike::GetParentObject() const {
+ return mParent;
+}
+
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestInterfaceSetlike.h b/dom/bindings/test/TestInterfaceSetlike.h
new file mode 100644
index 0000000000..c99a0240ea
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceSetlike.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestInterfaceSetlike_h
+#define mozilla_dom_TestInterfaceSetlike_h
+
+#include "nsWrapperCache.h"
+#include "nsCOMPtr.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+
+class ErrorResult;
+
+namespace dom {
+
+class GlobalObject;
+
+// Implementation of test binding for webidl setlike interfaces, using
+// primitives for key type.
+class TestInterfaceSetlike final : public nsISupports, public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(TestInterfaceSetlike)
+ explicit TestInterfaceSetlike(JSContext* aCx, nsPIDOMWindowInner* aParent);
+ nsPIDOMWindowInner* GetParentObject() const;
+ virtual JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+ static already_AddRefed<TestInterfaceSetlike> Constructor(
+ const GlobalObject& aGlobal, ErrorResult& rv);
+
+ private:
+ virtual ~TestInterfaceSetlike() = default;
+ nsCOMPtr<nsPIDOMWindowInner> mParent;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TestInterfaceSetlike_h
diff --git a/dom/bindings/test/TestInterfaceSetlikeNode.cpp b/dom/bindings/test/TestInterfaceSetlikeNode.cpp
new file mode 100644
index 0000000000..5d01c50b42
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceSetlikeNode.cpp
@@ -0,0 +1,53 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/dom/TestInterfaceSetlikeNode.h"
+#include "mozilla/dom/TestInterfaceJSMaplikeSetlikeIterableBinding.h"
+#include "nsPIDOMWindow.h"
+#include "mozilla/dom/BindingUtils.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(TestInterfaceSetlikeNode, mParent)
+
+NS_IMPL_CYCLE_COLLECTING_ADDREF(TestInterfaceSetlikeNode)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(TestInterfaceSetlikeNode)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TestInterfaceSetlikeNode)
+ NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+NS_INTERFACE_MAP_END
+
+TestInterfaceSetlikeNode::TestInterfaceSetlikeNode(JSContext* aCx,
+ nsPIDOMWindowInner* aParent)
+ : mParent(aParent) {}
+
+// static
+already_AddRefed<TestInterfaceSetlikeNode>
+TestInterfaceSetlikeNode::Constructor(const GlobalObject& aGlobal,
+ ErrorResult& aRv) {
+ nsCOMPtr<nsPIDOMWindowInner> window =
+ do_QueryInterface(aGlobal.GetAsSupports());
+ if (!window) {
+ aRv.Throw(NS_ERROR_FAILURE);
+ return nullptr;
+ }
+
+ RefPtr<TestInterfaceSetlikeNode> r =
+ new TestInterfaceSetlikeNode(nullptr, window);
+ return r.forget();
+}
+
+JSObject* TestInterfaceSetlikeNode::WrapObject(
+ JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
+ return TestInterfaceSetlikeNode_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+nsPIDOMWindowInner* TestInterfaceSetlikeNode::GetParentObject() const {
+ return mParent;
+}
+
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestInterfaceSetlikeNode.h b/dom/bindings/test/TestInterfaceSetlikeNode.h
new file mode 100644
index 0000000000..c4efdeab19
--- /dev/null
+++ b/dom/bindings/test/TestInterfaceSetlikeNode.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestInterfaceSetlikeNode_h
+#define mozilla_dom_TestInterfaceSetlikeNode_h
+
+#include "nsWrapperCache.h"
+#include "nsCOMPtr.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+
+class ErrorResult;
+
+namespace dom {
+
+class GlobalObject;
+
+// Implementation of test binding for webidl setlike interfaces, using
+// primitives for key type.
+class TestInterfaceSetlikeNode final : public nsISupports,
+ public nsWrapperCache {
+ public:
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(TestInterfaceSetlikeNode)
+ explicit TestInterfaceSetlikeNode(JSContext* aCx,
+ nsPIDOMWindowInner* aParent);
+ nsPIDOMWindowInner* GetParentObject() const;
+ virtual JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+ static already_AddRefed<TestInterfaceSetlikeNode> Constructor(
+ const GlobalObject& aGlobal, ErrorResult& rv);
+
+ private:
+ virtual ~TestInterfaceSetlikeNode() = default;
+ nsCOMPtr<nsPIDOMWindowInner> mParent;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_TestInterfaceSetlikeNode_h
diff --git a/dom/bindings/test/TestJSImplGen.webidl b/dom/bindings/test/TestJSImplGen.webidl
new file mode 100644
index 0000000000..418d199212
--- /dev/null
+++ b/dom/bindings/test/TestJSImplGen.webidl
@@ -0,0 +1,887 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+typedef TestJSImplInterface AnotherNameForTestJSImplInterface;
+typedef TestJSImplInterface YetAnotherNameForTestJSImplInterface;
+typedef TestJSImplInterface? NullableTestJSImplInterface;
+
+callback MyTestCallback = undefined();
+
+enum MyTestEnum {
+ "a",
+ "b"
+};
+
+[Exposed=Window, JSImplementation="@mozilla.org/test-js-impl-interface;1"]
+interface TestJSImplInterface {
+ // We don't support multiple constructors or legacy factory functions
+ // for JS-implemented WebIDL.
+ [Throws]
+ constructor(DOMString str, unsigned long num, boolean? boolArg,
+ TestInterface? iface, long arg1,
+ DictForConstructor dict, any any1,
+ object obj1,
+ object? obj2, sequence<Dict> seq, optional any any2,
+ optional object obj3,
+ optional object? obj4,
+ Uint8Array typedArr,
+ ArrayBuffer arrayBuf);
+
+ // Integer types
+ // XXXbz add tests for throwing versions of all the integer stuff
+ readonly attribute byte readonlyByte;
+ attribute byte writableByte;
+ undefined passByte(byte arg);
+ byte receiveByte();
+ undefined passOptionalByte(optional byte arg);
+ undefined passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
+ undefined passOptionalByteWithDefault(optional byte arg = 0);
+ undefined passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
+ undefined passNullableByte(byte? arg);
+ undefined passOptionalNullableByte(optional byte? arg);
+ undefined passVariadicByte(byte... arg);
+ // [Cached] is not supported in JS-implemented WebIDL.
+ //[Cached, Pure]
+ //readonly attribute byte cachedByte;
+ //[Cached, Constant]
+ //readonly attribute byte cachedConstantByte;
+ //[Cached, Pure]
+ //attribute byte cachedWritableByte;
+ [Affects=Nothing]
+ attribute byte sideEffectFreeByte;
+ [Affects=Nothing, DependsOn=DOMState]
+ attribute byte domDependentByte;
+ [Affects=Nothing, DependsOn=Nothing]
+ readonly attribute byte constantByte;
+ [DependsOn=DeviceState, Affects=Nothing]
+ readonly attribute byte deviceStateDependentByte;
+ [Affects=Nothing]
+ byte returnByteSideEffectFree();
+ [Affects=Nothing, DependsOn=DOMState]
+ byte returnDOMDependentByte();
+ [Affects=Nothing, DependsOn=Nothing]
+ byte returnConstantByte();
+ [DependsOn=DeviceState, Affects=Nothing]
+ byte returnDeviceStateDependentByte();
+
+ readonly attribute short readonlyShort;
+ attribute short writableShort;
+ undefined passShort(short arg);
+ short receiveShort();
+ undefined passOptionalShort(optional short arg);
+ undefined passOptionalShortWithDefault(optional short arg = 5);
+
+ readonly attribute long readonlyLong;
+ attribute long writableLong;
+ undefined passLong(long arg);
+ long receiveLong();
+ undefined passOptionalLong(optional long arg);
+ undefined passOptionalLongWithDefault(optional long arg = 7);
+
+ readonly attribute long long readonlyLongLong;
+ attribute long long writableLongLong;
+ undefined passLongLong(long long arg);
+ long long receiveLongLong();
+ undefined passOptionalLongLong(optional long long arg);
+ undefined passOptionalLongLongWithDefault(optional long long arg = -12);
+
+ readonly attribute octet readonlyOctet;
+ attribute octet writableOctet;
+ undefined passOctet(octet arg);
+ octet receiveOctet();
+ undefined passOptionalOctet(optional octet arg);
+ undefined passOptionalOctetWithDefault(optional octet arg = 19);
+
+ readonly attribute unsigned short readonlyUnsignedShort;
+ attribute unsigned short writableUnsignedShort;
+ undefined passUnsignedShort(unsigned short arg);
+ unsigned short receiveUnsignedShort();
+ undefined passOptionalUnsignedShort(optional unsigned short arg);
+ undefined passOptionalUnsignedShortWithDefault(optional unsigned short arg = 2);
+
+ readonly attribute unsigned long readonlyUnsignedLong;
+ attribute unsigned long writableUnsignedLong;
+ undefined passUnsignedLong(unsigned long arg);
+ unsigned long receiveUnsignedLong();
+ undefined passOptionalUnsignedLong(optional unsigned long arg);
+ undefined passOptionalUnsignedLongWithDefault(optional unsigned long arg = 6);
+
+ readonly attribute unsigned long long readonlyUnsignedLongLong;
+ attribute unsigned long long writableUnsignedLongLong;
+ undefined passUnsignedLongLong(unsigned long long arg);
+ unsigned long long receiveUnsignedLongLong();
+ undefined passOptionalUnsignedLongLong(optional unsigned long long arg);
+ undefined passOptionalUnsignedLongLongWithDefault(optional unsigned long long arg = 17);
+
+ attribute float writableFloat;
+ attribute unrestricted float writableUnrestrictedFloat;
+ attribute float? writableNullableFloat;
+ attribute unrestricted float? writableNullableUnrestrictedFloat;
+ attribute double writableDouble;
+ attribute unrestricted double writableUnrestrictedDouble;
+ attribute double? writableNullableDouble;
+ attribute unrestricted double? writableNullableUnrestrictedDouble;
+ undefined passFloat(float arg1, unrestricted float arg2,
+ float? arg3, unrestricted float? arg4,
+ double arg5, unrestricted double arg6,
+ double? arg7, unrestricted double? arg8,
+ sequence<float> arg9, sequence<unrestricted float> arg10,
+ sequence<float?> arg11, sequence<unrestricted float?> arg12,
+ sequence<double> arg13, sequence<unrestricted double> arg14,
+ sequence<double?> arg15, sequence<unrestricted double?> arg16);
+ [LenientFloat]
+ undefined passLenientFloat(float arg1, unrestricted float arg2,
+ float? arg3, unrestricted float? arg4,
+ double arg5, unrestricted double arg6,
+ double? arg7, unrestricted double? arg8,
+ sequence<float> arg9,
+ sequence<unrestricted float> arg10,
+ sequence<float?> arg11,
+ sequence<unrestricted float?> arg12,
+ sequence<double> arg13,
+ sequence<unrestricted double> arg14,
+ sequence<double?> arg15,
+ sequence<unrestricted double?> arg16);
+ [LenientFloat]
+ attribute float lenientFloatAttr;
+ [LenientFloat]
+ attribute double lenientDoubleAttr;
+
+ // Castable interface types
+ // XXXbz add tests for throwing versions of all the castable interface stuff
+ TestJSImplInterface receiveSelf();
+ TestJSImplInterface? receiveNullableSelf();
+
+ TestJSImplInterface receiveWeakSelf();
+ TestJSImplInterface? receiveWeakNullableSelf();
+
+ // A version to test for casting to TestJSImplInterface&
+ undefined passSelf(TestJSImplInterface arg);
+ undefined passNullableSelf(TestJSImplInterface? arg);
+ attribute TestJSImplInterface nonNullSelf;
+ attribute TestJSImplInterface? nullableSelf;
+ // [Cached] is not supported in JS-implemented WebIDL.
+ //[Cached, Pure]
+ //readonly attribute TestJSImplInterface cachedSelf;
+ // Optional arguments
+ undefined passOptionalSelf(optional TestJSImplInterface? arg);
+ undefined passOptionalNonNullSelf(optional TestJSImplInterface arg);
+ undefined passOptionalSelfWithDefault(optional TestJSImplInterface? arg = null);
+
+ // Non-wrapper-cache interface types
+ [NewObject]
+ TestNonWrapperCacheInterface receiveNonWrapperCacheInterface();
+ [NewObject]
+ TestNonWrapperCacheInterface? receiveNullableNonWrapperCacheInterface();
+
+ [NewObject]
+ sequence<TestNonWrapperCacheInterface> receiveNonWrapperCacheInterfaceSequence();
+ [NewObject]
+ sequence<TestNonWrapperCacheInterface?> receiveNullableNonWrapperCacheInterfaceSequence();
+ [NewObject]
+ sequence<TestNonWrapperCacheInterface>? receiveNonWrapperCacheInterfaceNullableSequence();
+ [NewObject]
+ sequence<TestNonWrapperCacheInterface?>? receiveNullableNonWrapperCacheInterfaceNullableSequence();
+
+ // External interface types
+ TestExternalInterface receiveExternal();
+ TestExternalInterface? receiveNullableExternal();
+ TestExternalInterface receiveWeakExternal();
+ TestExternalInterface? receiveWeakNullableExternal();
+ undefined passExternal(TestExternalInterface arg);
+ undefined passNullableExternal(TestExternalInterface? arg);
+ attribute TestExternalInterface nonNullExternal;
+ attribute TestExternalInterface? nullableExternal;
+ // Optional arguments
+ undefined passOptionalExternal(optional TestExternalInterface? arg);
+ undefined passOptionalNonNullExternal(optional TestExternalInterface arg);
+ undefined passOptionalExternalWithDefault(optional TestExternalInterface? arg = null);
+
+ // Callback interface types
+ TestCallbackInterface receiveCallbackInterface();
+ TestCallbackInterface? receiveNullableCallbackInterface();
+ TestCallbackInterface receiveWeakCallbackInterface();
+ TestCallbackInterface? receiveWeakNullableCallbackInterface();
+ undefined passCallbackInterface(TestCallbackInterface arg);
+ undefined passNullableCallbackInterface(TestCallbackInterface? arg);
+ attribute TestCallbackInterface nonNullCallbackInterface;
+ attribute TestCallbackInterface? nullableCallbackInterface;
+ // Optional arguments
+ undefined passOptionalCallbackInterface(optional TestCallbackInterface? arg);
+ undefined passOptionalNonNullCallbackInterface(optional TestCallbackInterface arg);
+ undefined passOptionalCallbackInterfaceWithDefault(optional TestCallbackInterface? arg = null);
+
+ // Sequence types
+ // [Cached] is not supported in JS-implemented WebIDL.
+ //[Cached, Pure]
+ //readonly attribute sequence<long> readonlySequence;
+ //[Cached, Pure]
+ //readonly attribute sequence<Dict> readonlySequenceOfDictionaries;
+ //[Cached, Pure]
+ //readonly attribute sequence<Dict>? readonlyNullableSequenceOfDictionaries;
+ //[Cached, Pure, Frozen]
+ //readonly attribute sequence<long> readonlyFrozenSequence;
+ //[Cached, Pure, Frozen]
+ //readonly attribute sequence<long>? readonlyFrozenNullableSequence;
+ sequence<long> receiveSequence();
+ sequence<long>? receiveNullableSequence();
+ sequence<long?> receiveSequenceOfNullableInts();
+ sequence<long?>? receiveNullableSequenceOfNullableInts();
+ undefined passSequence(sequence<long> arg);
+ undefined passNullableSequence(sequence<long>? arg);
+ undefined passSequenceOfNullableInts(sequence<long?> arg);
+ undefined passOptionalSequenceOfNullableInts(optional sequence<long?> arg);
+ undefined passOptionalNullableSequenceOfNullableInts(optional sequence<long?>? arg);
+ sequence<TestJSImplInterface> receiveCastableObjectSequence();
+ sequence<TestCallbackInterface> receiveCallbackObjectSequence();
+ sequence<TestJSImplInterface?> receiveNullableCastableObjectSequence();
+ sequence<TestCallbackInterface?> receiveNullableCallbackObjectSequence();
+ sequence<TestJSImplInterface>? receiveCastableObjectNullableSequence();
+ sequence<TestJSImplInterface?>? receiveNullableCastableObjectNullableSequence();
+ sequence<TestJSImplInterface> receiveWeakCastableObjectSequence();
+ sequence<TestJSImplInterface?> receiveWeakNullableCastableObjectSequence();
+ sequence<TestJSImplInterface>? receiveWeakCastableObjectNullableSequence();
+ sequence<TestJSImplInterface?>? receiveWeakNullableCastableObjectNullableSequence();
+ undefined passCastableObjectSequence(sequence<TestJSImplInterface> arg);
+ undefined passNullableCastableObjectSequence(sequence<TestJSImplInterface?> arg);
+ undefined passCastableObjectNullableSequence(sequence<TestJSImplInterface>? arg);
+ undefined passNullableCastableObjectNullableSequence(sequence<TestJSImplInterface?>? arg);
+ undefined passOptionalSequence(optional sequence<long> arg);
+ undefined passOptionalSequenceWithDefaultValue(optional sequence<long> arg = []);
+ undefined passOptionalNullableSequence(optional sequence<long>? arg);
+ undefined passOptionalNullableSequenceWithDefaultValue(optional sequence<long>? arg = null);
+ undefined passOptionalNullableSequenceWithDefaultValue2(optional sequence<long>? arg = []);
+ undefined passOptionalObjectSequence(optional sequence<TestJSImplInterface> arg);
+ undefined passExternalInterfaceSequence(sequence<TestExternalInterface> arg);
+ undefined passNullableExternalInterfaceSequence(sequence<TestExternalInterface?> arg);
+
+ sequence<DOMString> receiveStringSequence();
+ sequence<ByteString> receiveByteStringSequence();
+ sequence<UTF8String> receiveUTF8StringSequence();
+ // Callback interface problem. See bug 843261.
+ //undefined passStringSequence(sequence<DOMString> arg);
+ sequence<any> receiveAnySequence();
+ sequence<any>? receiveNullableAnySequence();
+ //XXXbz No support for sequence of sequence return values yet.
+ //sequence<sequence<any>> receiveAnySequenceSequence();
+
+ sequence<object> receiveObjectSequence();
+ sequence<object?> receiveNullableObjectSequence();
+
+ undefined passSequenceOfSequences(sequence<sequence<long>> arg);
+ undefined passSequenceOfSequencesOfSequences(sequence<sequence<sequence<long>>> arg);
+ //XXXbz No support for sequence of sequence return values yet.
+ //sequence<sequence<long>> receiveSequenceOfSequences();
+
+ // record types
+ undefined passRecord(record<DOMString, long> arg);
+ undefined passNullableRecord(record<DOMString, long>? arg);
+ undefined passRecordOfNullableInts(record<DOMString, long?> arg);
+ undefined passOptionalRecordOfNullableInts(optional record<DOMString, long?> arg);
+ undefined passOptionalNullableRecordOfNullableInts(optional record<DOMString, long?>? arg);
+ undefined passCastableObjectRecord(record<DOMString, TestInterface> arg);
+ undefined passNullableCastableObjectRecord(record<DOMString, TestInterface?> arg);
+ undefined passCastableObjectNullableRecord(record<DOMString, TestInterface>? arg);
+ undefined passNullableCastableObjectNullableRecord(record<DOMString, TestInterface?>? arg);
+ undefined passOptionalRecord(optional record<DOMString, long> arg);
+ undefined passOptionalNullableRecord(optional record<DOMString, long>? arg);
+ undefined passOptionalNullableRecordWithDefaultValue(optional record<DOMString, long>? arg = null);
+ undefined passOptionalObjectRecord(optional record<DOMString, TestInterface> arg);
+ undefined passExternalInterfaceRecord(record<DOMString, TestExternalInterface> arg);
+ undefined passNullableExternalInterfaceRecord(record<DOMString, TestExternalInterface?> arg);
+ undefined passStringRecord(record<DOMString, DOMString> arg);
+ undefined passByteStringRecord(record<DOMString, ByteString> arg);
+ undefined passUTF8StringRecord(record<DOMString, UTF8String> arg);
+ undefined passRecordOfRecords(record<DOMString, record<DOMString, long>> arg);
+ record<DOMString, long> receiveRecord();
+ record<DOMString, long>? receiveNullableRecord();
+ record<DOMString, long?> receiveRecordOfNullableInts();
+ record<DOMString, long?>? receiveNullableRecordOfNullableInts();
+ //XXXbz No support for record of records return values yet.
+ //record<DOMString, record<DOMString, long>> receiveRecordOfRecords();
+ record<DOMString, any> receiveAnyRecord();
+
+ // Typed array types
+ undefined passArrayBuffer(ArrayBuffer arg);
+ undefined passNullableArrayBuffer(ArrayBuffer? arg);
+ undefined passOptionalArrayBuffer(optional ArrayBuffer arg);
+ undefined passOptionalNullableArrayBuffer(optional ArrayBuffer? arg);
+ undefined passOptionalNullableArrayBufferWithDefaultValue(optional ArrayBuffer? arg= null);
+ undefined passArrayBufferView(ArrayBufferView arg);
+ undefined passInt8Array(Int8Array arg);
+ undefined passInt16Array(Int16Array arg);
+ undefined passInt32Array(Int32Array arg);
+ undefined passUint8Array(Uint8Array arg);
+ undefined passUint16Array(Uint16Array arg);
+ undefined passUint32Array(Uint32Array arg);
+ undefined passUint8ClampedArray(Uint8ClampedArray arg);
+ undefined passFloat32Array(Float32Array arg);
+ undefined passFloat64Array(Float64Array arg);
+ undefined passSequenceOfArrayBuffers(sequence<ArrayBuffer> arg);
+ undefined passSequenceOfNullableArrayBuffers(sequence<ArrayBuffer?> arg);
+ undefined passRecordOfArrayBuffers(record<DOMString, ArrayBuffer> arg);
+ undefined passRecordOfNullableArrayBuffers(record<DOMString, ArrayBuffer?> arg);
+ undefined passVariadicTypedArray(Float32Array... arg);
+ undefined passVariadicNullableTypedArray(Float32Array?... arg);
+ Uint8Array receiveUint8Array();
+ attribute Uint8Array uint8ArrayAttr;
+
+ // DOMString types
+ undefined passString(DOMString arg);
+ undefined passNullableString(DOMString? arg);
+ undefined passOptionalString(optional DOMString arg);
+ undefined passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
+ undefined passOptionalNullableString(optional DOMString? arg);
+ undefined passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
+ undefined passVariadicString(DOMString... arg);
+
+ // ByteString types
+ undefined passByteString(ByteString arg);
+ undefined passNullableByteString(ByteString? arg);
+ undefined passOptionalByteString(optional ByteString arg);
+ undefined passOptionalByteStringWithDefaultValue(optional ByteString arg = "abc");
+ undefined passOptionalNullableByteString(optional ByteString? arg);
+ undefined passOptionalNullableByteStringWithDefaultValue(optional ByteString? arg = null);
+ undefined passVariadicByteString(ByteString... arg);
+ undefined passUnionByteString((ByteString or long) arg);
+ undefined passOptionalUnionByteString(optional (ByteString or long) arg);
+ undefined passOptionalUnionByteStringWithDefaultValue(optional (ByteString or long) arg = "abc");
+
+ // UTF8String types
+ undefined passUTF8String(UTF8String arg);
+ undefined passNullableUTF8String(UTF8String? arg);
+ undefined passOptionalUTF8String(optional UTF8String arg);
+ undefined passOptionalUTF8StringWithDefaultValue(optional UTF8String arg = "abc");
+ undefined passOptionalNullableUTF8String(optional UTF8String? arg);
+ undefined passOptionalNullableUTF8StringWithDefaultValue(optional UTF8String? arg = null);
+ undefined passVariadicUTF8String(UTF8String... arg);
+ undefined passUnionUTF8String((UTF8String or long) arg);
+ undefined passOptionalUnionUTF8String(optional (UTF8String or long) arg);
+ undefined passOptionalUnionUTF8StringWithDefaultValue(optional (UTF8String or long) arg = "abc");
+
+ // USVString types
+ undefined passSVS(USVString arg);
+ undefined passNullableSVS(USVString? arg);
+ undefined passOptionalSVS(optional USVString arg);
+ undefined passOptionalSVSWithDefaultValue(optional USVString arg = "abc");
+ undefined passOptionalNullableSVS(optional USVString? arg);
+ undefined passOptionalNullableSVSWithDefaultValue(optional USVString? arg = null);
+ undefined passVariadicSVS(USVString... arg);
+ USVString receiveSVS();
+
+ // JSString types
+ undefined passJSString(JSString arg);
+ // undefined passNullableJSString(JSString? arg); // NOT SUPPORTED YET
+ // undefined passOptionalJSString(optional JSString arg); // NOT SUPPORTED YET
+ undefined passOptionalJSStringWithDefaultValue(optional JSString arg = "abc");
+ // undefined passOptionalNullableJSString(optional JSString? arg); // NOT SUPPORTED YET
+ // undefined passOptionalNullableJSStringWithDefaultValue(optional JSString? arg = null); // NOT SUPPORTED YET
+ // undefined passVariadicJSString(JSString... arg); // NOT SUPPORTED YET
+ // undefined passRecordOfJSString(record<DOMString, JSString> arg); // NOT SUPPORTED YET
+ // undefined passSequenceOfJSString(sequence<JSString> arg); // NOT SUPPORTED YET
+ // undefined passUnionJSString((JSString or long) arg); // NOT SUPPORTED YET
+ JSString receiveJSString();
+ // sequence<JSString> receiveJSStringSequence(); // NOT SUPPORTED YET
+ // (JSString or long) receiveJSStringUnion(); // NOT SUPPORTED YET
+ // record<DOMString, JSString> receiveJSStringRecord(); // NOT SUPPORTED YET
+ readonly attribute JSString readonlyJSStringAttr;
+ attribute JSString jsStringAttr;
+
+ // Enumerated types
+ undefined passEnum(MyTestEnum arg);
+ undefined passNullableEnum(MyTestEnum? arg);
+ undefined passOptionalEnum(optional MyTestEnum arg);
+ undefined passEnumWithDefault(optional MyTestEnum arg = "a");
+ undefined passOptionalNullableEnum(optional MyTestEnum? arg);
+ undefined passOptionalNullableEnumWithDefaultValue(optional MyTestEnum? arg = null);
+ undefined passOptionalNullableEnumWithDefaultValue2(optional MyTestEnum? arg = "a");
+ MyTestEnum receiveEnum();
+ MyTestEnum? receiveNullableEnum();
+ attribute MyTestEnum enumAttribute;
+ readonly attribute MyTestEnum readonlyEnumAttribute;
+
+ // Callback types
+ undefined passCallback(MyTestCallback arg);
+ undefined passNullableCallback(MyTestCallback? arg);
+ undefined passOptionalCallback(optional MyTestCallback arg);
+ undefined passOptionalNullableCallback(optional MyTestCallback? arg);
+ undefined passOptionalNullableCallbackWithDefaultValue(optional MyTestCallback? arg = null);
+ MyTestCallback receiveCallback();
+ MyTestCallback? receiveNullableCallback();
+ // Hmm. These two don't work, I think because I need a locally modified version of TestTreatAsNullCallback.
+ //undefined passNullableTreatAsNullCallback(TestTreatAsNullCallback? arg);
+ //undefined passOptionalNullableTreatAsNullCallback(optional TestTreatAsNullCallback? arg);
+ undefined passOptionalNullableTreatAsNullCallbackWithDefaultValue(optional TestTreatAsNullCallback? arg = null);
+
+ // Any types
+ undefined passAny(any arg);
+ undefined passVariadicAny(any... arg);
+ undefined passOptionalAny(optional any arg);
+ undefined passAnyDefaultNull(optional any arg = null);
+ undefined passSequenceOfAny(sequence<any> arg);
+ undefined passNullableSequenceOfAny(sequence<any>? arg);
+ undefined passOptionalSequenceOfAny(optional sequence<any> arg);
+ undefined passOptionalNullableSequenceOfAny(optional sequence<any>? arg);
+ undefined passOptionalSequenceOfAnyWithDefaultValue(optional sequence<any>? arg = null);
+ undefined passSequenceOfSequenceOfAny(sequence<sequence<any>> arg);
+ undefined passSequenceOfNullableSequenceOfAny(sequence<sequence<any>?> arg);
+ undefined passNullableSequenceOfNullableSequenceOfAny(sequence<sequence<any>?>? arg);
+ undefined passOptionalNullableSequenceOfNullableSequenceOfAny(optional sequence<sequence<any>?>? arg);
+ undefined passRecordOfAny(record<DOMString, any> arg);
+ undefined passNullableRecordOfAny(record<DOMString, any>? arg);
+ undefined passOptionalRecordOfAny(optional record<DOMString, any> arg);
+ undefined passOptionalNullableRecordOfAny(optional record<DOMString, any>? arg);
+ undefined passOptionalRecordOfAnyWithDefaultValue(optional record<DOMString, any>? arg = null);
+ undefined passRecordOfRecordOfAny(record<DOMString, record<DOMString, any>> arg);
+ undefined passRecordOfNullableRecordOfAny(record<DOMString, record<DOMString, any>?> arg);
+ undefined passNullableRecordOfNullableRecordOfAny(record<DOMString, record<DOMString, any>?>? arg);
+ undefined passOptionalNullableRecordOfNullableRecordOfAny(optional record<DOMString, record<DOMString, any>?>? arg);
+ undefined passOptionalNullableRecordOfNullableSequenceOfAny(optional record<DOMString, sequence<any>?>? arg);
+ undefined passOptionalNullableSequenceOfNullableRecordOfAny(optional sequence<record<DOMString, any>?>? arg);
+ any receiveAny();
+
+ // object types
+ undefined passObject(object arg);
+ undefined passVariadicObject(object... arg);
+ undefined passNullableObject(object? arg);
+ undefined passVariadicNullableObject(object... arg);
+ undefined passOptionalObject(optional object arg);
+ undefined passOptionalNullableObject(optional object? arg);
+ undefined passOptionalNullableObjectWithDefaultValue(optional object? arg = null);
+ undefined passSequenceOfObject(sequence<object> arg);
+ undefined passSequenceOfNullableObject(sequence<object?> arg);
+ undefined passNullableSequenceOfObject(sequence<object>? arg);
+ undefined passOptionalNullableSequenceOfNullableSequenceOfObject(optional sequence<sequence<object>?>? arg);
+ undefined passOptionalNullableSequenceOfNullableSequenceOfNullableObject(optional sequence<sequence<object?>?>? arg);
+ undefined passRecordOfObject(record<DOMString, object> arg);
+ object receiveObject();
+ object? receiveNullableObject();
+
+ // Union types
+ undefined passUnion((object or long) arg);
+ // Some union tests are debug-only to aundefined creating all those
+ // unused union types in opt builds.
+#ifdef DEBUG
+ undefined passUnion2((long or boolean) arg);
+ undefined passUnion3((object or long or boolean) arg);
+ undefined passUnion4((Node or long or boolean) arg);
+ undefined passUnion5((object or boolean) arg);
+ undefined passUnion6((object or DOMString) arg);
+ undefined passUnion7((object or DOMString or long) arg);
+ undefined passUnion8((object or DOMString or boolean) arg);
+ undefined passUnion9((object or DOMString or long or boolean) arg);
+ undefined passUnion10(optional (EventInit or long) arg = {});
+ undefined passUnion11(optional (CustomEventInit or long) arg = {});
+ undefined passUnion12(optional (EventInit or long) arg = 5);
+ undefined passUnion13(optional (object or long?) arg = null);
+ undefined passUnion14(optional (object or long?) arg = 5);
+ undefined passUnion15((sequence<long> or long) arg);
+ undefined passUnion16(optional (sequence<long> or long) arg);
+ undefined passUnion17(optional (sequence<long>? or long) arg = 5);
+ undefined passUnion18((sequence<object> or long) arg);
+ undefined passUnion19(optional (sequence<object> or long) arg);
+ undefined passUnion20(optional (sequence<object> or long) arg = []);
+ undefined passUnion21((record<DOMString, long> or long) arg);
+ undefined passUnion22((record<DOMString, object> or long) arg);
+ undefined passUnion23((sequence<ImageData> or long) arg);
+ undefined passUnion24((sequence<ImageData?> or long) arg);
+ undefined passUnion25((sequence<sequence<ImageData>> or long) arg);
+ undefined passUnion26((sequence<sequence<ImageData?>> or long) arg);
+ undefined passUnion27(optional (sequence<DOMString> or EventInit) arg = {});
+ undefined passUnion28(optional (EventInit or sequence<DOMString>) arg = {});
+ undefined passUnionWithCallback((EventHandler or long) arg);
+ undefined passUnionWithByteString((ByteString or long) arg);
+ undefined passUnionWithUTF8String((UTF8String or long) arg);
+ undefined passUnionWithRecord((record<DOMString, DOMString> or DOMString) arg);
+ undefined passUnionWithRecordAndSequence((record<DOMString, DOMString> or sequence<DOMString>) arg);
+ undefined passUnionWithSequenceAndRecord((sequence<DOMString> or record<DOMString, DOMString>) arg);
+ undefined passUnionWithSVS((USVString or long) arg);
+#endif
+ undefined passUnionWithNullable((object? or long) arg);
+ undefined passNullableUnion((object or long)? arg);
+ undefined passOptionalUnion(optional (object or long) arg);
+ undefined passOptionalNullableUnion(optional (object or long)? arg);
+ undefined passOptionalNullableUnionWithDefaultValue(optional (object or long)? arg = null);
+ //undefined passUnionWithInterfaces((TestJSImplInterface or TestExternalInterface) arg);
+ //undefined passUnionWithInterfacesAndNullable((TestJSImplInterface? or TestExternalInterface) arg);
+ //undefined passUnionWithSequence((sequence<object> or long) arg);
+ undefined passUnionWithArrayBuffer((UTF8String or ArrayBuffer) arg);
+ undefined passUnionWithArrayBufferOrNull((UTF8String or ArrayBuffer?) arg);
+ undefined passUnionWithTypedArrays((ArrayBufferView or ArrayBuffer) arg);
+ undefined passUnionWithTypedArraysOrNull((ArrayBufferView or ArrayBuffer?) arg);
+ undefined passUnionWithString((DOMString or object) arg);
+ // Using an enum in a union. Note that we use some enum not declared in our
+ // binding file, because UnionTypes.h will need to include the binding header
+ // for this enum. Pick an enum from an interface that won't drag in too much
+ // stuff.
+ undefined passUnionWithEnum((SupportedType or object) arg);
+
+ // Trying to use a callback in a union won't include the test
+ // headers, unfortunately, so won't compile.
+ // undefined passUnionWithCallback((MyTestCallback or long) arg);
+ undefined passUnionWithObject((object or long) arg);
+ //undefined passUnionWithDict((Dict or long) arg);
+
+ undefined passUnionWithDefaultValue1(optional (double or DOMString) arg = "");
+ undefined passUnionWithDefaultValue2(optional (double or DOMString) arg = 1);
+ undefined passUnionWithDefaultValue3(optional (double or DOMString) arg = 1.5);
+ undefined passUnionWithDefaultValue4(optional (float or DOMString) arg = "");
+ undefined passUnionWithDefaultValue5(optional (float or DOMString) arg = 1);
+ undefined passUnionWithDefaultValue6(optional (float or DOMString) arg = 1.5);
+ undefined passUnionWithDefaultValue7(optional (unrestricted double or DOMString) arg = "");
+ undefined passUnionWithDefaultValue8(optional (unrestricted double or DOMString) arg = 1);
+ undefined passUnionWithDefaultValue9(optional (unrestricted double or DOMString) arg = 1.5);
+ undefined passUnionWithDefaultValue10(optional (unrestricted double or DOMString) arg = Infinity);
+ undefined passUnionWithDefaultValue11(optional (unrestricted float or DOMString) arg = "");
+ undefined passUnionWithDefaultValue12(optional (unrestricted float or DOMString) arg = 1);
+ undefined passUnionWithDefaultValue13(optional (unrestricted float or DOMString) arg = Infinity);
+ undefined passUnionWithDefaultValue14(optional (double or ByteString) arg = "");
+ undefined passUnionWithDefaultValue15(optional (double or ByteString) arg = 1);
+ undefined passUnionWithDefaultValue16(optional (double or ByteString) arg = 1.5);
+ undefined passUnionWithDefaultValue17(optional (double or SupportedType) arg = "text/html");
+ undefined passUnionWithDefaultValue18(optional (double or SupportedType) arg = 1);
+ undefined passUnionWithDefaultValue19(optional (double or SupportedType) arg = 1.5);
+ undefined passUnionWithDefaultValue20(optional (double or USVString) arg = "abc");
+ undefined passUnionWithDefaultValue21(optional (double or USVString) arg = 1);
+ undefined passUnionWithDefaultValue22(optional (double or USVString) arg = 1.5);
+ undefined passUnionWithDefaultValue23(optional (double or UTF8String) arg = "");
+ undefined passUnionWithDefaultValue24(optional (double or UTF8String) arg = 1);
+ undefined passUnionWithDefaultValue25(optional (double or UTF8String) arg = 1.5);
+
+ undefined passNullableUnionWithDefaultValue1(optional (double or DOMString)? arg = "");
+ undefined passNullableUnionWithDefaultValue2(optional (double or DOMString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue3(optional (double or DOMString)? arg = null);
+ undefined passNullableUnionWithDefaultValue4(optional (float or DOMString)? arg = "");
+ undefined passNullableUnionWithDefaultValue5(optional (float or DOMString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue6(optional (float or DOMString)? arg = null);
+ undefined passNullableUnionWithDefaultValue7(optional (unrestricted double or DOMString)? arg = "");
+ undefined passNullableUnionWithDefaultValue8(optional (unrestricted double or DOMString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue9(optional (unrestricted double or DOMString)? arg = null);
+ undefined passNullableUnionWithDefaultValue10(optional (unrestricted float or DOMString)? arg = "");
+ undefined passNullableUnionWithDefaultValue11(optional (unrestricted float or DOMString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue12(optional (unrestricted float or DOMString)? arg = null);
+ undefined passNullableUnionWithDefaultValue13(optional (double or ByteString)? arg = "");
+ undefined passNullableUnionWithDefaultValue14(optional (double or ByteString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue15(optional (double or ByteString)? arg = 1.5);
+ undefined passNullableUnionWithDefaultValue16(optional (double or ByteString)? arg = null);
+ undefined passNullableUnionWithDefaultValue17(optional (double or SupportedType)? arg = "text/html");
+ undefined passNullableUnionWithDefaultValue18(optional (double or SupportedType)? arg = 1);
+ undefined passNullableUnionWithDefaultValue19(optional (double or SupportedType)? arg = 1.5);
+ undefined passNullableUnionWithDefaultValue20(optional (double or SupportedType)? arg = null);
+ undefined passNullableUnionWithDefaultValue21(optional (double or USVString)? arg = "abc");
+ undefined passNullableUnionWithDefaultValue22(optional (double or USVString)? arg = 1);
+ undefined passNullableUnionWithDefaultValue23(optional (double or USVString)? arg = 1.5);
+ undefined passNullableUnionWithDefaultValue24(optional (double or USVString)? arg = null);
+ undefined passNullableUnionWithDefaultValue25(optional (double or UTF8String)? arg = "");
+ undefined passNullableUnionWithDefaultValue26(optional (double or UTF8String)? arg = 1);
+ undefined passNullableUnionWithDefaultValue27(optional (double or UTF8String)? arg = 1.5);
+ undefined passNullableUnionWithDefaultValue28(optional (double or UTF8String)? arg = null);
+
+ undefined passSequenceOfUnions(sequence<(CanvasPattern or CanvasGradient)> arg);
+ undefined passSequenceOfUnions2(sequence<(object or long)> arg);
+ undefined passVariadicUnion((CanvasPattern or CanvasGradient)... arg);
+
+ undefined passSequenceOfNullableUnions(sequence<(CanvasPattern or CanvasGradient)?> arg);
+ undefined passVariadicNullableUnion((CanvasPattern or CanvasGradient)?... arg);
+ undefined passRecordOfUnions(record<DOMString, (CanvasPattern or CanvasGradient)> arg);
+ // XXXbz no move constructor on some unions
+ // undefined passRecordOfUnions2(record<DOMString, (object or long)> arg);
+
+ (CanvasPattern or CanvasGradient) receiveUnion();
+ (object or long) receiveUnion2();
+ (CanvasPattern? or CanvasGradient) receiveUnionContainingNull();
+ (CanvasPattern or CanvasGradient)? receiveNullableUnion();
+ (object or long)? receiveNullableUnion2();
+
+ attribute (CanvasPattern or CanvasGradient) writableUnion;
+ attribute (CanvasPattern? or CanvasGradient) writableUnionContainingNull;
+ attribute (CanvasPattern or CanvasGradient)? writableNullableUnion;
+
+ // Promise types
+ undefined passPromise(Promise<any> arg);
+ undefined passOptionalPromise(optional Promise<any> arg);
+ undefined passPromiseSequence(sequence<Promise<any>> arg);
+ Promise<any> receivePromise();
+ Promise<any> receiveAddrefedPromise();
+
+ // binaryNames tests
+ [BinaryName="methodRenamedTo"]
+ undefined methodRenamedFrom();
+ [BinaryName="methodRenamedTo"]
+ undefined methodRenamedFrom(byte argument);
+ [BinaryName="attributeGetterRenamedTo"]
+ readonly attribute byte attributeGetterRenamedFrom;
+ [BinaryName="attributeRenamedTo"]
+ attribute byte attributeRenamedFrom;
+
+ undefined passDictionary(optional Dict x = {});
+ undefined passDictionary2(Dict x);
+ // [Cached] is not supported in JS-implemented WebIDL.
+ //[Cached, Pure]
+ //readonly attribute Dict readonlyDictionary;
+ //[Cached, Pure]
+ //readonly attribute Dict? readonlyNullableDictionary;
+ //[Cached, Pure]
+ //attribute Dict writableDictionary;
+ //[Cached, Pure, Frozen]
+ //readonly attribute Dict readonlyFrozenDictionary;
+ //[Cached, Pure, Frozen]
+ //readonly attribute Dict? readonlyFrozenNullableDictionary;
+ //[Cached, Pure, Frozen]
+ //attribute Dict writableFrozenDictionary;
+ Dict receiveDictionary();
+ Dict? receiveNullableDictionary();
+ undefined passOtherDictionary(optional GrandparentDict x = {});
+ undefined passSequenceOfDictionaries(sequence<Dict> x);
+ undefined passRecordOfDictionaries(record<DOMString, GrandparentDict> x);
+ // No support for nullable dictionaries inside a sequence (nor should there be)
+ // undefined passSequenceOfNullableDictionaries(sequence<Dict?> x);
+ undefined passDictionaryOrLong(optional Dict x = {});
+ undefined passDictionaryOrLong(long x);
+
+ undefined passDictContainingDict(optional DictContainingDict arg = {});
+ undefined passDictContainingSequence(optional DictContainingSequence arg = {});
+ DictContainingSequence receiveDictContainingSequence();
+ undefined passVariadicDictionary(Dict... arg);
+
+ // EnforceRange/Clamp tests
+ undefined dontEnforceRangeOrClamp(byte arg);
+ undefined doEnforceRange([EnforceRange] byte arg);
+ undefined doEnforceRangeNullable([EnforceRange] byte? arg);
+ undefined doClamp([Clamp] byte arg);
+ undefined doClampNullable([Clamp] byte? arg);
+ attribute [EnforceRange] byte enforcedByte;
+ attribute [EnforceRange] byte? enforcedByteNullable;
+ attribute [Clamp] byte clampedByte;
+ attribute [Clamp] byte? clampedByteNullable;
+
+ // Typedefs
+ const myLong myLongConstant = 5;
+ undefined exerciseTypedefInterfaces1(AnotherNameForTestJSImplInterface arg);
+ AnotherNameForTestJSImplInterface exerciseTypedefInterfaces2(NullableTestJSImplInterface arg);
+ undefined exerciseTypedefInterfaces3(YetAnotherNameForTestJSImplInterface arg);
+
+ // Deprecated methods and attributes
+ [Deprecated="Components"]
+ attribute byte deprecatedAttribute;
+ [Deprecated="Components"]
+ byte deprecatedMethod();
+ [Deprecated="Components"]
+ undefined deprecatedMethodWithContext(any arg);
+
+ // Static methods and attributes
+ // FIXME: Bug 863952 Static things are not supported yet
+ /*
+ static attribute boolean staticAttribute;
+ static undefined staticMethod(boolean arg);
+ static undefined staticMethodWithContext(any arg);
+
+ // Deprecated static methods and attributes
+ [Deprecated="Components"]
+ static attribute byte staticDeprecatedAttribute;
+ [Deprecated="Components"]
+ static byte staticDeprecatedMethod();
+ [Deprecated="Components"]
+ static byte staticDeprecatedMethodWithContext();
+ */
+
+ // Overload resolution tests
+ //undefined overload1(DOMString... strs);
+ boolean overload1(TestJSImplInterface arg);
+ TestJSImplInterface overload1(DOMString strs, TestJSImplInterface arg);
+ undefined overload2(TestJSImplInterface arg);
+ undefined overload2(optional Dict arg = {});
+ undefined overload2(boolean arg);
+ undefined overload2(DOMString arg);
+ undefined overload3(TestJSImplInterface arg);
+ undefined overload3(MyTestCallback arg);
+ undefined overload3(boolean arg);
+ undefined overload4(TestJSImplInterface arg);
+ undefined overload4(TestCallbackInterface arg);
+ undefined overload4(DOMString arg);
+ undefined overload5(long arg);
+ undefined overload5(MyTestEnum arg);
+ undefined overload6(long arg);
+ undefined overload6(boolean arg);
+ undefined overload7(long arg);
+ undefined overload7(boolean arg);
+ undefined overload7(ByteString arg);
+ undefined overload8(long arg);
+ undefined overload8(TestJSImplInterface arg);
+ undefined overload9(long? arg);
+ undefined overload9(DOMString arg);
+ undefined overload10(long? arg);
+ undefined overload10(object arg);
+ undefined overload11(long arg);
+ undefined overload11(DOMString? arg);
+ undefined overload12(long arg);
+ undefined overload12(boolean? arg);
+ undefined overload13(long? arg);
+ undefined overload13(boolean arg);
+ undefined overload14(optional long arg);
+ undefined overload14(TestInterface arg);
+ undefined overload15(long arg);
+ undefined overload15(optional TestInterface arg);
+ undefined overload16(long arg);
+ undefined overload16(optional TestInterface? arg);
+ undefined overload17(sequence<long> arg);
+ undefined overload17(record<DOMString, long> arg);
+ undefined overload18(record<DOMString, DOMString> arg);
+ undefined overload18(sequence<DOMString> arg);
+ undefined overload19(sequence<long> arg);
+ undefined overload19(optional Dict arg = {});
+ undefined overload20(optional Dict arg = {});
+ undefined overload20(sequence<long> arg);
+
+ // Variadic handling
+ undefined passVariadicThirdArg(DOMString arg1, long arg2, TestJSImplInterface... arg3);
+
+ // Conditionally exposed methods/attributes
+ [Pref="dom.webidl.test1"]
+ readonly attribute boolean prefable1;
+ [Pref="dom.webidl.test1"]
+ readonly attribute boolean prefable2;
+ [Pref="dom.webidl.test2"]
+ readonly attribute boolean prefable3;
+ [Pref="dom.webidl.test2"]
+ readonly attribute boolean prefable4;
+ [Pref="dom.webidl.test1"]
+ readonly attribute boolean prefable5;
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean prefable6;
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean prefable7;
+ [Pref="dom.webidl.test2", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean prefable8;
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean prefable9;
+ [Pref="dom.webidl.test1"]
+ undefined prefable10();
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ undefined prefable11();
+ [Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ readonly attribute boolean prefable12;
+ [Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ undefined prefable13();
+ [Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ readonly attribute boolean prefable14;
+ [Func="TestFuncControlledMember"]
+ readonly attribute boolean prefable15;
+ [Func="TestFuncControlledMember"]
+ readonly attribute boolean prefable16;
+ [Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ undefined prefable17();
+ [Func="TestFuncControlledMember"]
+ undefined prefable18();
+ [Func="TestFuncControlledMember"]
+ undefined prefable19();
+ [Pref="dom.webidl.test1", Func="TestFuncControlledMember", ChromeOnly]
+ undefined prefable20();
+
+ // Conditionally exposed methods/attributes involving [SecureContext]
+ [SecureContext]
+ readonly attribute boolean conditionalOnSecureContext1;
+ [SecureContext, Pref="dom.webidl.test1"]
+ readonly attribute boolean conditionalOnSecureContext2;
+ [SecureContext, Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ readonly attribute boolean conditionalOnSecureContext3;
+ [SecureContext, Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ readonly attribute boolean conditionalOnSecureContext4;
+ [SecureContext]
+ undefined conditionalOnSecureContext5();
+ [SecureContext, Pref="dom.webidl.test1"]
+ undefined conditionalOnSecureContext6();
+ [SecureContext, Pref="dom.webidl.test1", Func="nsGenericHTMLElement::LegacyTouchAPIEnabled"]
+ undefined conditionalOnSecureContext7();
+ [SecureContext, Pref="dom.webidl.test1", Func="TestFuncControlledMember"]
+ undefined conditionalOnSecureContext8();
+
+ // Miscellania
+ [LegacyLenientThis] attribute long attrWithLenientThis;
+ // FIXME: Bug 863954 Unforgeable things get all confused when
+ // non-JS-implemented interfaces inherit from JS-implemented ones or vice
+ // versa.
+ // [Unforgeable] readonly attribute long unforgeableAttr;
+ // [Unforgeable, ChromeOnly] readonly attribute long unforgeableAttr2;
+ // [Unforgeable] long unforgeableMethod();
+ // [Unforgeable, ChromeOnly] long unforgeableMethod2();
+ // FIXME: Bug 863955 No stringifiers yet
+ // stringifier;
+ undefined passRenamedInterface(TestRenamedInterface arg);
+ [PutForwards=writableByte] readonly attribute TestJSImplInterface putForwardsAttr;
+ [PutForwards=writableByte, LegacyLenientThis] readonly attribute TestJSImplInterface putForwardsAttr2;
+ [PutForwards=writableByte, ChromeOnly] readonly attribute TestJSImplInterface putForwardsAttr3;
+ [Throws] undefined throwingMethod();
+ [Throws] attribute boolean throwingAttr;
+ [GetterThrows] attribute boolean throwingGetterAttr;
+ [SetterThrows] attribute boolean throwingSetterAttr;
+ [CanOOM] undefined canOOMMethod();
+ [CanOOM] attribute boolean canOOMAttr;
+ [GetterCanOOM] attribute boolean canOOMGetterAttr;
+ [SetterCanOOM] attribute boolean canOOMSetterAttr;
+ [CEReactions] undefined ceReactionsMethod();
+ [CEReactions] undefined ceReactionsMethodOverload();
+ [CEReactions] undefined ceReactionsMethodOverload(DOMString bar);
+ [CEReactions] attribute boolean ceReactionsAttr;
+ // NeedsSubjectPrincipal not supported on JS-implemented things for
+ // now, because we always pass in the caller principal anyway.
+ // [NeedsSubjectPrincipal] undefined needsSubjectPrincipalMethod();
+ // [NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
+ // legacycaller short(unsigned long arg1, TestInterface arg2);
+ undefined passArgsWithDefaults(optional long arg1,
+ optional TestInterface? arg2 = null,
+ optional Dict arg3 = {}, optional double arg4 = 5.0,
+ optional float arg5);
+ attribute any toJSONShouldSkipThis;
+ attribute TestParentInterface toJSONShouldSkipThis2;
+ attribute TestCallbackInterface toJSONShouldSkipThis3;
+ [Default] object toJSON();
+
+ attribute byte dashed-attribute;
+ undefined dashed-method();
+
+ // [NonEnumerable] tests
+ [NonEnumerable]
+ attribute boolean nonEnumerableAttr;
+ [NonEnumerable]
+ const boolean nonEnumerableConst = true;
+ [NonEnumerable]
+ undefined nonEnumerableMethod();
+
+ // [AllowShared] tests
+ attribute [AllowShared] ArrayBufferViewTypedef allowSharedArrayBufferViewTypedef;
+ attribute [AllowShared] ArrayBufferView allowSharedArrayBufferView;
+ attribute [AllowShared] ArrayBufferView? allowSharedNullableArrayBufferView;
+ attribute [AllowShared] ArrayBuffer allowSharedArrayBuffer;
+ attribute [AllowShared] ArrayBuffer? allowSharedNullableArrayBuffer;
+
+ undefined passAllowSharedArrayBufferViewTypedef(AllowSharedArrayBufferViewTypedef foo);
+ undefined passAllowSharedArrayBufferView([AllowShared] ArrayBufferView foo);
+ undefined passAllowSharedNullableArrayBufferView([AllowShared] ArrayBufferView? foo);
+ undefined passAllowSharedArrayBuffer([AllowShared] ArrayBuffer foo);
+ undefined passAllowSharedNullableArrayBuffer([AllowShared] ArrayBuffer? foo);
+ undefined passUnionArrayBuffer((DOMString or ArrayBuffer) foo);
+ undefined passUnionAllowSharedArrayBuffer((DOMString or [AllowShared] ArrayBuffer) foo);
+
+ // If you add things here, add them to TestCodeGen as well
+};
+
+[Exposed=Window]
+interface TestCImplementedInterface : TestJSImplInterface {
+};
+
+[Exposed=Window]
+interface TestCImplementedInterface2 {
+};
+
+[LegacyNoInterfaceObject,
+ JSImplementation="@mozilla.org/test-js-impl-interface;2",
+ Exposed=Window]
+interface TestJSImplNoInterfaceObject {
+ // [Cached] is not supported in JS-implemented WebIDL.
+ //[Cached, Pure]
+ //readonly attribute byte cachedByte;
+};
diff --git a/dom/bindings/test/TestJSImplInheritanceGen.webidl b/dom/bindings/test/TestJSImplInheritanceGen.webidl
new file mode 100644
index 0000000000..b4b66d20a0
--- /dev/null
+++ b/dom/bindings/test/TestJSImplInheritanceGen.webidl
@@ -0,0 +1,39 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+[Exposed=Window, JSImplementation="@mozilla.org/test-js-impl-interface2;1"]
+interface TestJSImplInterface2 : TestCImplementedInterface {
+ [Throws]
+ constructor();
+};
+
+[Exposed=Window, JSImplementation="@mozilla.org/test-js-impl-interface3;1"]
+interface TestJSImplInterface3 : TestCImplementedInterface2 {
+ [Throws]
+ constructor();
+};
+
+// Important: TestJSImplInterface5 needs to come before TestJSImplInterface6 in
+// this file to test what it's trying to test.
+[Exposed=Window, JSImplementation="@mozilla.org/test-js-impl-interface5;1"]
+interface TestJSImplInterface5 : TestJSImplInterface6 {
+ [Throws]
+ constructor();
+};
+
+// Important: TestJSImplInterface6 needs to come after TestJSImplInterface3 in
+// this file to test what it's trying to test.
+[Exposed=Window, JSImplementation="@mozilla.org/test-js-impl-interface6;1"]
+interface TestJSImplInterface6 : TestJSImplInterface3 {
+ [Throws]
+ constructor();
+};
+
+[Exposed=Window, JSImplementation="@mozilla.org/test-js-impl-interface4;1"]
+interface TestJSImplInterface4 : EventTarget {
+ [Throws]
+ constructor();
+};
diff --git a/dom/bindings/test/TestTrialInterface.cpp b/dom/bindings/test/TestTrialInterface.cpp
new file mode 100644
index 0000000000..e0b9bb44f9
--- /dev/null
+++ b/dom/bindings/test/TestTrialInterface.cpp
@@ -0,0 +1,24 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#include "mozilla/dom/TestTrialInterface.h"
+#include "mozilla/dom/TestFunctionsBinding.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(TestTrialInterface)
+
+JSObject* TestTrialInterface::WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) {
+ return TestTrialInterface_Binding::Wrap(aCx, this, aGivenProto);
+}
+
+already_AddRefed<TestTrialInterface> TestTrialInterface::Constructor(
+ const GlobalObject& aGlobalObject) {
+ return MakeAndAddRef<TestTrialInterface>();
+}
+
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/TestTrialInterface.h b/dom/bindings/test/TestTrialInterface.h
new file mode 100644
index 0000000000..1fa746b09a
--- /dev/null
+++ b/dom/bindings/test/TestTrialInterface.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#ifndef mozilla_dom_TestTrialInterface_h
+#define mozilla_dom_TestTrialInterface_h
+
+#include "js/TypeDecls.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/dom/BindingDeclarations.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsWrapperCache.h"
+
+namespace mozilla::dom {
+
+class TestTrialInterface final : public nsWrapperCache {
+ public:
+ NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(TestTrialInterface)
+ NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(TestTrialInterface)
+
+ public:
+ TestTrialInterface() = default;
+
+ static already_AddRefed<TestTrialInterface> Constructor(
+ const GlobalObject& aGlobalObject);
+
+ protected:
+ ~TestTrialInterface() = default;
+
+ public:
+ nsISupports* GetParentObject() const { return nullptr; }
+ JSObject* WrapObject(JSContext*, JS::Handle<JSObject*> aGivenProto) override;
+};
+
+} // namespace mozilla::dom
+
+#endif // mozilla_dom_TestTrialInterface_h
diff --git a/dom/bindings/test/TestTypedef.webidl b/dom/bindings/test/TestTypedef.webidl
new file mode 100644
index 0000000000..7f758c79e8
--- /dev/null
+++ b/dom/bindings/test/TestTypedef.webidl
@@ -0,0 +1,7 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/.
+ */
+
+typedef TestInterface YetAnotherNameForTestInterface;
diff --git a/dom/bindings/test/WrapperCachedNonISupportsTestInterface.cpp b/dom/bindings/test/WrapperCachedNonISupportsTestInterface.cpp
new file mode 100644
index 0000000000..aa69488a09
--- /dev/null
+++ b/dom/bindings/test/WrapperCachedNonISupportsTestInterface.cpp
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#include "mozilla/dom/WrapperCachedNonISupportsTestInterface.h"
+#include "mozilla/dom/TestFunctionsBinding.h"
+
+namespace mozilla::dom {
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WrapperCachedNonISupportsTestInterface)
+
+JSObject* WrapperCachedNonISupportsTestInterface::WrapObject(
+ JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
+ return WrapperCachedNonISupportsTestInterface_Binding::Wrap(aCx, this,
+ aGivenProto);
+}
+
+already_AddRefed<WrapperCachedNonISupportsTestInterface>
+WrapperCachedNonISupportsTestInterface::Constructor(
+ const GlobalObject& aGlobalObject) {
+ RefPtr<WrapperCachedNonISupportsTestInterface> result =
+ new WrapperCachedNonISupportsTestInterface();
+ return result.forget();
+}
+
+} // namespace mozilla::dom
diff --git a/dom/bindings/test/WrapperCachedNonISupportsTestInterface.h b/dom/bindings/test/WrapperCachedNonISupportsTestInterface.h
new file mode 100644
index 0000000000..c226d03456
--- /dev/null
+++ b/dom/bindings/test/WrapperCachedNonISupportsTestInterface.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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/. */
+
+#ifndef mozilla_dom_WrapperCachedNonISupportsTestInterface_h
+#define mozilla_dom_WrapperCachedNonISupportsTestInterface_h
+
+#include "js/TypeDecls.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/dom/BindingDeclarations.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsWrapperCache.h"
+
+namespace mozilla {
+namespace dom {
+
+class WrapperCachedNonISupportsTestInterface final : public nsWrapperCache {
+ public:
+ NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(
+ WrapperCachedNonISupportsTestInterface)
+ NS_DECL_CYCLE_COLLECTION_NATIVE_WRAPPERCACHE_CLASS(
+ WrapperCachedNonISupportsTestInterface)
+
+ public:
+ WrapperCachedNonISupportsTestInterface() = default;
+
+ static already_AddRefed<WrapperCachedNonISupportsTestInterface> Constructor(
+ const GlobalObject& aGlobalObject);
+
+ protected:
+ ~WrapperCachedNonISupportsTestInterface() = default;
+
+ public:
+ nsISupports* GetParentObject() const { return nullptr; }
+
+ virtual JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) override;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_WrapperCachedNonISupportsTestInterface_h
diff --git a/dom/bindings/test/chrome.toml b/dom/bindings/test/chrome.toml
new file mode 100644
index 0000000000..0986974ece
--- /dev/null
+++ b/dom/bindings/test/chrome.toml
@@ -0,0 +1,28 @@
+[DEFAULT]
+support-files = [
+ "!/dom/bindings/test/file_bug775543.html",
+ "!/dom/bindings/test/file_document_location_set_via_xray.html",
+ "!/dom/bindings/test/file_dom_xrays.html",
+ "!/dom/bindings/test/file_proxies_via_xray.html",
+]
+
+["test_bug775543.html"]
+
+["test_bug1123516_maplikesetlikechrome.xhtml"]
+skip-if = ["!debug"] # TestFunctions is only available in debug builds
+
+["test_bug1287912.html"]
+
+["test_bug1457051.html"]
+
+["test_document_location_set_via_xray.html"]
+
+["test_document_location_via_xray_cached.html"]
+
+["test_dom_xrays.html"]
+skip-if = ["debug == false"] # TestFunctions is only available in debug builds
+
+["test_interfaceLength_chrome.html"]
+skip-if = ["debug == false"] # TestFunctions is only available in debug builds
+
+["test_proxies_via_xray.html"]
diff --git a/dom/bindings/test/file_InstanceOf.html b/dom/bindings/test/file_InstanceOf.html
new file mode 100644
index 0000000000..61e2bc295e
--- /dev/null
+++ b/dom/bindings/test/file_InstanceOf.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<script type="application/javascript">
+function runTest() {
+ return [ parent.HTMLElement.prototype instanceof Element,
+ parent.HTMLElement.prototype instanceof parent.Element ];
+}
+</script>
+</body>
+</html>
diff --git a/dom/bindings/test/file_barewordGetsWindow_frame1.html b/dom/bindings/test/file_barewordGetsWindow_frame1.html
new file mode 100644
index 0000000000..f20ba8a257
--- /dev/null
+++ b/dom/bindings/test/file_barewordGetsWindow_frame1.html
@@ -0,0 +1 @@
+OLD \ No newline at end of file
diff --git a/dom/bindings/test/file_barewordGetsWindow_frame2.html b/dom/bindings/test/file_barewordGetsWindow_frame2.html
new file mode 100644
index 0000000000..5f08364e3b
--- /dev/null
+++ b/dom/bindings/test/file_barewordGetsWindow_frame2.html
@@ -0,0 +1 @@
+NEW \ No newline at end of file
diff --git a/dom/bindings/test/file_bug1808352_frame.html b/dom/bindings/test/file_bug1808352_frame.html
new file mode 100644
index 0000000000..aaff3b561f
--- /dev/null
+++ b/dom/bindings/test/file_bug1808352_frame.html
@@ -0,0 +1,4 @@
+<script>
+document.domain = "mochi.test";
+window.parent.loadedFrame();
+</script>
diff --git a/dom/bindings/test/file_bug1808352b_frame.html b/dom/bindings/test/file_bug1808352b_frame.html
new file mode 100644
index 0000000000..513f32e4da
--- /dev/null
+++ b/dom/bindings/test/file_bug1808352b_frame.html
@@ -0,0 +1,3 @@
+<script>
+window.opener.loadedFrame();
+</script>
diff --git a/dom/bindings/test/file_bug775543.html b/dom/bindings/test/file_bug775543.html
new file mode 100644
index 0000000000..856d14ab0e
--- /dev/null
+++ b/dom/bindings/test/file_bug775543.html
@@ -0,0 +1,5 @@
+<body>
+<script>
+var worker = new Worker("a");
+</script>
+</body>
diff --git a/dom/bindings/test/file_document_location_set_via_xray.html b/dom/bindings/test/file_document_location_set_via_xray.html
new file mode 100644
index 0000000000..323acba666
--- /dev/null
+++ b/dom/bindings/test/file_document_location_set_via_xray.html
@@ -0,0 +1,5 @@
+<body>
+<script>
+document.x = 5;
+</script>
+</body>
diff --git a/dom/bindings/test/file_dom_xrays.html b/dom/bindings/test/file_dom_xrays.html
new file mode 100644
index 0000000000..3a71a3d836
--- /dev/null
+++ b/dom/bindings/test/file_dom_xrays.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+ <script>
+ document.expando = 42;
+ document.shadowedIframe = 42;
+ Object.setPrototypeOf(document, Object.create(HTMLDocument.prototype,
+ {
+ shadowedIframe: { value: 42 },
+ iframe: { value: 42 },
+ defaultView: { value: 42 },
+ addEventListener: { value: 42 },
+ toString: { value: 42 },
+ }));
+ document.documentElement.expando = 42;
+ Object.defineProperty(document.documentElement, "version", { value: 42 });
+ </script>
+ <iframe name="shadowedIframe" id="shadowedIframe"></iframe>
+ <iframe name="iframe" id="iframe"></iframe>
+ <iframe name="document" id="document"></iframe>
+ <iframe name="self" id="self"></iframe>
+ <iframe name="addEventListener" id="addEventListener"></iframe>
+ <iframe name="toString" id="toString"></iframe>
+ <iframe name="item" id="item"></iframe>
+</html>
diff --git a/dom/bindings/test/file_proxies_via_xray.html b/dom/bindings/test/file_proxies_via_xray.html
new file mode 100644
index 0000000000..135c1f5301
--- /dev/null
+++ b/dom/bindings/test/file_proxies_via_xray.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+ <script>
+ document.x = 5;
+ </script>
+ <img id="y" name="y"></div>
+ <img id="z" name="z"></div>
+</html>
diff --git a/dom/bindings/test/forOf_iframe.html b/dom/bindings/test/forOf_iframe.html
new file mode 100644
index 0000000000..91417aba0e
--- /dev/null
+++ b/dom/bindings/test/forOf_iframe.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>iframe content for test_forOf_iframe.html</title>
+</head>
+<body>
+ <div id="basket">
+ <span id="egg0"></span>
+ <span id="egg1"><span id="duckling1"></span></span>
+ <span id="egg2"></span>
+ </div>
+</body>
+</html>
diff --git a/dom/bindings/test/mochitest.toml b/dom/bindings/test/mochitest.toml
new file mode 100644
index 0000000000..bf3df97da8
--- /dev/null
+++ b/dom/bindings/test/mochitest.toml
@@ -0,0 +1,207 @@
+[DEFAULT]
+support-files = [
+ "file_InstanceOf.html",
+ "file_bug775543.html",
+ "file_document_location_set_via_xray.html",
+ "file_dom_xrays.html",
+ "file_proxies_via_xray.html",
+ "forOf_iframe.html",
+ "!/js/xpconnect/tests/mochitest/file_empty.html",
+]
+prefs = [
+ "javascript.options.large_arraybuffers=true",
+ "javascript.options.experimental.arraybuffer_resizable=true",
+ "javascript.options.experimental.sharedarraybuffer_growable=true",
+]
+
+["test_ByteString.html"]
+
+["test_InstanceOf.html"]
+
+["test_Object.prototype_props.html"]
+
+["test_async_iterable.html"]
+skip-if = ["!debug"]
+
+["test_async_stacks.html"]
+
+["test_attributes_on_types.html"]
+skip-if = ["!debug"]
+
+["test_barewordGetsWindow.html"]
+support-files = [
+ "file_barewordGetsWindow_frame1.html",
+ "file_barewordGetsWindow_frame2.html",
+]
+
+["test_bug560072.html"]
+
+["test_bug742191.html"]
+
+["test_bug759621.html"]
+
+["test_bug773326.html"]
+
+["test_bug788369.html"]
+
+["test_bug852846.html"]
+
+["test_bug862092.html"]
+
+["test_bug1036214.html"]
+skip-if = [
+ "!debug",
+ "http3",
+ "http2",
+]
+
+["test_bug1041646.html"]
+
+["test_bug1123516_maplikesetlike.html"]
+skip-if = ["!debug"]
+
+["test_bug1123875.html"]
+
+["test_bug1808352.html"]
+skip-if = [
+ "http3", # Bug 1827526
+ "http2",
+]
+support-files = ["file_bug1808352_frame.html"]
+
+["test_bug1808352b.html"]
+support-files = ["file_bug1808352b_frame.html"]
+
+["test_callback_across_document_open.html"]
+
+["test_callback_default_thisval.html"]
+
+["test_callback_exceptions.html"]
+
+["test_cloneAndImportNode.html"]
+
+["test_crossOriginWindowSymbolAccess.html"]
+skip-if = [
+ "http3",
+ "http2",
+]
+
+["test_defineProperty.html"]
+
+["test_domProxyArrayLengthGetter.html"]
+
+["test_enums.html"]
+
+["test_exceptionSanitization.html"]
+skip-if = ["!debug"]
+
+["test_exceptionThrowing.html"]
+
+["test_exception_messages.html"]
+
+["test_exception_options_from_jsimplemented.html"]
+skip-if = ["!debug"]
+
+["test_exceptions_from_jsimplemented.html"]
+tags = "webrtc"
+
+["test_forOf.html"]
+
+["test_integers.html"]
+
+["test_interfaceLength.html"]
+skip-if = ["!debug"]
+
+["test_interfaceName.html"]
+
+["test_interfaceToString.html"]
+
+["test_iterable.html"]
+skip-if = ["!debug"]
+
+["test_jsimplemented_cross_realm_this.html"]
+skip-if = ["!debug"]
+
+["test_jsimplemented_eventhandler.html"]
+skip-if = ["!debug"]
+
+["test_jsimplemented_subclassing.html"]
+
+["test_large_arraybuffers.html"]
+skip-if = [
+ "!debug",
+ "bits == 32", # Large ArrayBuffers are only supported on 64-bit platforms.
+]
+
+["test_large_imageData.html"]
+
+["test_lenientThis.html"]
+
+["test_lookupGetter.html"]
+
+["test_namedNoIndexed.html"]
+
+["test_named_getter_enumerability.html"]
+
+["test_observablearray.html"]
+skip-if = ["!debug"]
+
+["test_observablearray_helper.html"]
+skip-if = ["!debug"]
+
+["test_observablearray_proxyhandler.html"]
+skip-if = ["!debug"]
+
+["test_oom_reporting.html"]
+
+["test_prefOnConstructor.html"]
+skip-if = ["!debug"]
+
+["test_primitive_this.html"]
+
+["test_promise_rejections_from_jsimplemented.html"]
+skip-if = ["!debug"]
+
+["test_proxy_accessors.html"]
+
+["test_proxy_expandos.html"]
+
+["test_proxy_missing_prop.html"]
+
+["test_remoteProxyAsPrototype.html"]
+
+["test_returnUnion.html"]
+skip-if = ["!debug"]
+
+["test_sequence_detection.html"]
+skip-if = ["!debug"]
+
+["test_sequence_wrapping.html"]
+subsuite = "gpu"
+
+["test_setWithNamedGetterNoNamedSetter.html"]
+
+["test_stringBindings.html"]
+skip-if = ["!debug"]
+
+["test_throwing_method_noDCE.html"]
+
+["test_toJSON.html"]
+skip-if = ["!debug"]
+
+["test_traceProtos.html"]
+
+["test_treat_non_object_as_null.html"]
+
+["test_unforgeablesonexpando.html"]
+
+["test_usvstring.html"]
+skip-if = ["!debug"]
+
+["test_worker_UnwrapArg.html"]
+
+["test_resizable_arraybufferview.html"]
+skip-if = [
+ "!debug",
+ "!nightly_build", # Bug 1670026
+]
diff --git a/dom/bindings/test/moz.build b/dom/bindings/test/moz.build
new file mode 100644
index 0000000000..b5c45301a6
--- /dev/null
+++ b/dom/bindings/test/moz.build
@@ -0,0 +1,69 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+DEFINES["IMPL_LIBXUL"] = True
+DEFINES["MOZILLA_INTERNAL_API"] = True
+
+# Do NOT export this library. We don't actually want our test code
+# being added to libxul or anything.
+
+Library("dombindings_test_s")
+
+MOCHITEST_MANIFESTS += ["mochitest.toml"]
+
+MOCHITEST_CHROME_MANIFESTS += ["chrome.toml"]
+
+TEST_WEBIDL_FILES += [
+ "TestCallback.webidl",
+ "TestDictionary.webidl",
+ "TestJSImplInheritanceGen.webidl",
+ "TestTypedef.webidl",
+]
+
+TESTING_JS_MODULES += [
+ "TestInterfaceJS.sys.mjs",
+]
+
+PREPROCESSED_TEST_WEBIDL_FILES += [
+ "TestCodeGen.webidl",
+ "TestExampleGen.webidl",
+ "TestJSImplGen.webidl",
+]
+
+WEBIDL_EXAMPLE_INTERFACES += [
+ "TestExampleInterface",
+ "TestExampleProxyInterface",
+ "TestExampleThrowingConstructorInterface",
+ "TestExampleWorkerInterface",
+]
+
+# Bug 932082 tracks having bindings use namespaced includes.
+LOCAL_INCLUDES += [
+ "!/dist/include/mozilla/dom",
+]
+
+LOCAL_INCLUDES += [
+ "!..",
+ "/dom/bindings",
+ "/js/xpconnect/src",
+ "/js/xpconnect/wrappers",
+]
+
+include("/ipc/chromium/chromium-config.mozbuild")
+
+if CONFIG["MOZ_DEBUG"]:
+ XPIDL_SOURCES += [
+ "mozITestInterfaceJS.idl",
+ ]
+
+ XPIDL_MODULE = "dom_bindings_test"
+
+# Because we don't actually link this code anywhere, we don't care about
+# their optimization level, so don't waste time on optimization.
+if CONFIG["CC_TYPE"] == "clang-cl":
+ CXXFLAGS += ["-Od"]
+else:
+ CXXFLAGS += ["-O0"]
diff --git a/dom/bindings/test/mozITestInterfaceJS.idl b/dom/bindings/test/mozITestInterfaceJS.idl
new file mode 100644
index 0000000000..7bfbc9b25f
--- /dev/null
+++ b/dom/bindings/test/mozITestInterfaceJS.idl
@@ -0,0 +1,21 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * 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/. */
+
+#include "nsISupports.idl"
+
+/**
+ * An interface to allow testing of binding interactions with JS-implemented
+ * XPCOM components. The actual implementation is TestInterfaceJS, just like
+ * for TestInteraceJS.webidl.
+ */
+
+[scriptable, uuid(9eeb2c12-ddd9-4734-8cfb-c0cdfb136e07)]
+interface mozITestInterfaceJS : nsISupports {
+ // Test throwing Components.results.NS_BINDING_ABORTED.
+ void testThrowNsresult();
+ // Test calling a C++ component which throws an nsresult exception.
+ void testThrowNsresultFromNative();
+};
diff --git a/dom/bindings/test/test_ByteString.html b/dom/bindings/test/test_ByteString.html
new file mode 100644
index 0000000000..c4285228e9
--- /dev/null
+++ b/dom/bindings/test/test_ByteString.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=796850
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for ByteString support</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=796850">Mozilla Bug 796850</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+ /** Test for Bug 796850 **/
+ var xhr = new XMLHttpRequest();
+ var caught = false;
+ try {
+ xhr.open("\u5427", "about:mozilla", true);
+ } catch (TypeError) {
+ caught = true;
+ }
+ ok(caught, "Character values > 255 not rejected for ByteString");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_InstanceOf.html b/dom/bindings/test/test_InstanceOf.html
new file mode 100644
index 0000000000..d04e4e4771
--- /dev/null
+++ b/dom/bindings/test/test_InstanceOf.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=748983
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 748983</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=748983">Mozilla Bug 748983</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 748983 **/
+
+SimpleTest.waitForExplicitFinish();
+
+function runTest() {
+ ok(document instanceof EventTarget, "document is an event target");
+ ok(new XMLHttpRequest() instanceof XMLHttpRequest, "instanceof should work on XHR");
+ ok(HTMLElement.prototype instanceof Node, "instanceof needs to walk the prototype chain");
+
+ var otherWin = document.getElementById("testFrame").contentWindow;
+
+ ok(otherWin.HTMLElement.prototype instanceof otherWin.Node, "Same-origin instanceof of a interface prototype object should work, even if called cross-origin");
+ ok(!(otherWin.HTMLElement.prototype instanceof Node), "Cross-origin instanceof of a interface prototype object shouldn't work");
+
+ // We need to reset HTMLElement.prototype.__proto__ to the original value
+ // before using anything from the harness, otherwise the harness code breaks
+ // in weird ways.
+ HTMLElement.prototype.__proto__ = otherWin.Element.prototype;
+ var [ shouldSucceed, shouldFail ] = otherWin.runTest();
+ shouldSucceed = shouldSucceed && HTMLElement.prototype instanceof otherWin.Element;
+ shouldFail = shouldFail && HTMLElement.prototype instanceof Element;
+ HTMLElement.prototype.__proto__ = Element.prototype;
+
+ ok(shouldSucceed, "If an interface prototype object is on the protochain then instanceof with the interface object should succeed");
+ ok(!shouldFail, "If an interface prototype object is not on the protochain then instanceof with the interface object should succeed");
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+<iframe id="testFrame" src="file_InstanceOf.html" onload="runTest()"></iframe>
+</body>
+</html>
diff --git a/dom/bindings/test/test_Object.prototype_props.html b/dom/bindings/test/test_Object.prototype_props.html
new file mode 100644
index 0000000000..b0e42dbc05
--- /dev/null
+++ b/dom/bindings/test/test_Object.prototype_props.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Test for bug 987110</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+/* global test, assert_array_equals */
+test(function() {
+ var props = Object.getOwnPropertyNames(Object.prototype);
+ // If you change this list, make sure it continues to match the list in
+ // Codegen.py's CGDictionary.getMemberDefinition method.
+ var expected = [
+ "constructor", "toString", "toLocaleString", "valueOf",
+ "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable",
+ "__defineGetter__", "__defineSetter__", "__lookupGetter__",
+ "__lookupSetter__", "__proto__",
+ ];
+ assert_array_equals(props.sort(), expected.sort());
+}, "Own properties of Object.prototype");
+</script>
diff --git a/dom/bindings/test/test_async_iterable.html b/dom/bindings/test/test_async_iterable.html
new file mode 100644
index 0000000000..8f1f04aea7
--- /dev/null
+++ b/dom/bindings/test/test_async_iterable.html
@@ -0,0 +1,300 @@
+<!-- Any copyright is dedicated to the Public Domain.
+- http://creativecommons.org/publicdomain/zero/1.0/ -->
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Test Async Iterable Interface</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ </head>
+ <body>
+ <script class="testbody" type="application/javascript">
+
+add_task(async function init() {
+ await SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]});
+});
+
+const singleValues = Array(10).fill(0).map((_, i) => i * 9 % 7);
+
+async function check_single_result_values(values, multiplier = 1) {
+ is(values.length, 10, `AsyncIterableSingle: should return 10 elements`);
+ for (let i = 0; i < 10; i++) {
+ let expected = singleValues[i] * multiplier;
+ is(values[i], expected,
+ `AsyncIterableSingle: should be ${expected}, get ${values[i]}`);
+ }
+}
+
+async function check_single_result(itr, multiplier = 1) {
+ let values = [];
+ for await (let v of itr) {
+ values.push(v);
+ }
+ check_single_result_values(values, multiplier);
+}
+
+async function test_data_single() {
+ info(`AsyncIterableSingle: Testing simple iterable creation and functionality`);
+
+ // eslint-disable-next-line no-undef
+ let itr = new TestInterfaceAsyncIterableSingle({ failToInit: true });
+ let initFailed = false;
+ try {
+ itr.values();
+ } catch (e) {
+ initFailed = true;
+ }
+ ok(initFailed,
+ "AsyncIterableSingle: A failure in asynchronous iterator initialization " +
+ "steps should propagate to the caller of the asynchronous iterator's " +
+ "constructor.");
+
+ // eslint-disable-next-line no-undef
+ itr = new TestInterfaceAsyncIterableSingle();
+ is(itr.values, itr[Symbol.asyncIterator],
+ `AsyncIterableSingle: Should be using @@asyncIterator for 'values'`);
+
+ await check_single_result(itr);
+ await check_single_result(itr.values());
+
+ // eslint-disable-next-line no-undef
+ itr = new TestInterfaceAsyncIterableSingleWithArgs();
+ is(itr.values, itr[Symbol.asyncIterator],
+ `AsyncIterableSingleWithArgs: Should be using @@asyncIterator for 'values'`);
+
+ await check_single_result(itr, 1);
+ await check_single_result(itr.values({ multiplier: 2 }), 2);
+
+ // eslint-disable-next-line no-undef
+ itr = new TestInterfaceAsyncIterableSingle();
+ let itrValues = itr.values();
+ let values = [];
+ for (let i = 0; i < 10; ++i) {
+ values.push(itrValues.next());
+ }
+ check_single_result_values(await Promise.all(values).then(v => v.map(w => w.value)));
+
+ // Test that there is only one ongoing promise at a time.
+ // Async iterables return a promise that is then resolved with the iterator
+ // value. We create an array of unresolved promises here, one promise for
+ // every result that we expect from the iterator. We pass that array of
+ // promises to the .value() method of the
+ // TestInterfaceAsyncIterableSingleWithArgs, and it will chain the resolving
+ // of each resulting iterator value on the corresponding promise from this
+ // array. We then resolve the promises in the array one by one in reverse
+ // order. This tries to make sure that the iterator always resolves the
+ // promises in the order of iteration.
+ let unblockers = [];
+ let blockingPromises = [];
+ for (let i = 0; i < 10; ++i) {
+ let unblocker;
+ let promise = new Promise((resolve, reject) => {
+ unblocker = resolve;
+ });
+ unblockers.push(unblocker);
+ blockingPromises.push(promise);
+ }
+
+ // eslint-disable-next-line no-undef
+ itr = new TestInterfaceAsyncIterableSingleWithArgs();
+ itrValues = itr.values({ blockingPromises });
+ values = [];
+ for (let i = 0; i < 10; ++i) {
+ values.push(itrValues.next());
+ }
+ unblockers.reverse();
+ for (let unblocker of unblockers) {
+ unblocker();
+ }
+
+ check_single_result_values(await Promise.all(values).then(v => v.map(w => w.value)));
+
+ // eslint-disable-next-line no-undef
+ itr = new TestInterfaceAsyncIterableSingleWithArgs();
+
+ let callCount = itr.returnCallCount;
+
+ let i = 0;
+ for await (let v of itr) {
+ if (++i > 1) {
+ break;
+ }
+ values.push(v);
+ }
+
+ is(itr.returnCallCount, callCount + 1,
+ `AsyncIterableSingle: breaking out of for-await-of loop should call "return"`);
+ is(itr.returnLastCalledWith, undefined,
+ `AsyncIterableSingleWithArgs: the asynchronous iterator return algorithm should be called with the argument that was passed in.`);
+
+ // eslint-disable-next-line no-undef
+ itr = new TestInterfaceAsyncIterableSingleWithArgs();
+
+ async function * yieldFromIterator () {
+ yield * itr
+ }
+
+ let yieldingIterator = yieldFromIterator();
+
+ let result = await yieldingIterator.next();
+ is(result.value, singleValues[0],
+ `AsyncIterableSingle: should be ${singleValues[0]}, get ${result.value}`);
+ result = await yieldingIterator.next();
+ is(result.value, singleValues[1],
+ `AsyncIterableSingle: should be ${singleValues[1]}, get ${result.value}`);
+
+ result = await yieldingIterator.return("abcd");
+ is(typeof result, "object",
+ `AsyncIterableSingleWithArgs: "return("abcd")" should return { done: true, value: "abcd" }`);
+ is(result.done, true,
+ `AsyncIterableSingleWithArgs: "return("abcd")" should return { done: true, value: "abcd" }`);
+ is(result.value, "abcd",
+ `AsyncIterableSingleWithArgs: "return("abcd")" should return { done: true, value: "abcd" }`);
+ is(itr.returnLastCalledWith, "abcd",
+ `AsyncIterableSingleWithArgs: the asynchronous iterator return algorithm should be called with the argument that was passed in.`);
+
+ result = await yieldingIterator.return("efgh");
+ is(typeof result, "object",
+ `AsyncIterableSingleWithArgs: "return("efgh")" should return { done: true, value: "efgh" }`);
+ is(result.done, true,
+ `AsyncIterableSingleWithArgs: "return("efgh")" should return { done: true, value: "efgh" }`);
+ is(result.value, "efgh",
+ `AsyncIterableSingleWithArgs: "return("efgh")" should return { done: true, value: "efgh" }`);
+ is(itr.returnLastCalledWith, "abcd",
+ `AsyncIterableSingleWithArgs: the asynchronous iterator return algorithm shouldn't be called if the iterator's 'is finished' flag is true already.`);
+
+ // eslint-disable-next-line no-undef
+ itr = new TestInterfaceAsyncIterableSingleWithArgs();
+ itrValues = itr.values({ failNextAfter: 1 });
+ await itrValues.next().then(({ value, done }) => {
+ is(value, singleValues[0], "First value is correct");
+ ok(!done, "Expecting more values");
+ return itrValues.next();
+ }).then(() => {
+ ok(false, "Second call to next() should convert failure to a rejected promise.");
+ return itrValues.next();
+ }).catch(() => {
+ ok(true, "Second call to next() should convert failure to a rejected promise.");
+ return itrValues.next();
+ }).then(({ done }) => {
+ ok(done, "An earlier failure in next() should set the async iterator's 'is finished' flag to true.");
+ }).catch(() => {
+ ok(false, "An earlier failure in next() shouldn't cause subsequent calls to return a rejected promise.");
+ });
+
+ // eslint-disable-next-line no-undef
+ itr = new TestInterfaceAsyncIterableSingleWithArgs();
+ itrValues = itr.values({ throwFromNext: true });
+ await itrValues.next().then(() => {
+ ok(false, "Should have rejected from the exception");
+ }).catch(() => {
+ ok(true, "Should have rejected from the exception");
+ });
+
+ // eslint-disable-next-line no-undef
+ itr = new TestInterfaceAsyncIterableSingleWithArgs();
+ itrValues = itr.values({ throwFromReturn: () => { throw new DOMException("Throw from return", "InvalidStateError"); } });
+ await itrValues.return().then(() => {
+ ok(false, "Should have rejected from the exception");
+ }).catch(() => {
+ ok(true, "Should have rejected from the exception");
+ });
+}
+
+async function test_data_double() {
+ info(`AsyncIterableDouble: Testing simple iterable creation and functionality`);
+
+ // eslint-disable-next-line no-undef
+ let itr = new TestInterfaceAsyncIterableDouble();
+ is(itr.entries, itr[Symbol.asyncIterator],
+ `AsyncIterableDouble: Should be using @@asyncIterator for 'entries'`);
+
+ let elements = [["a", "b"], ["c", "d"], ["e", "f"]];
+ let key_itr = itr.keys();
+ let value_itr = itr.values();
+ let entries_itr = itr.entries();
+ let key = await key_itr.next();
+ let value = await value_itr.next();
+ let entry = await entries_itr.next();
+ for (let i = 0; i < 3; ++i) {
+ is(key.value, elements[i][0], `AsyncIterableDouble: Key.value should be ${elements[i][0]}, got ${key.value}`);
+ is(key.done, false, `AsyncIterableDouble: Key.done should be false, got ${key.done}`);
+ is(value.value, elements[i][1], `AsyncIterableDouble: Value.value should be ${elements[i][1]}, got ${value.value}`);
+ is(value.done, false, `AsyncIterableDouble: Value.done should be false, got ${value.done}`);
+ is(entry.value[0], elements[i][0], `AsyncIterableDouble: Entry.value[0] should be ${elements[i][0]}, got ${entry.value[0]}`);
+ is(entry.value[1], elements[i][1], `AsyncIterableDouble: Entry.value[1] should be ${elements[i][1]}, got ${entry.value[1]}`);
+ is(entry.done, false, `AsyncIterableDouble: Entry.done should be false, got ${entry.done}`);
+
+ key = await key_itr.next();
+ value = await value_itr.next();
+ entry = await entries_itr.next();
+ }
+ is(key.value, undefined, `AsyncIterableDouble: Key.value should be ${undefined}, got ${key.value}`);
+ is(key.done, true, `AsyncIterableDouble: Key.done should be true, got ${key.done}`);
+ is(value.value, undefined, `AsyncIterableDouble: Value.value should be ${undefined}, got ${value.value}`);
+ is(value.done, true, `AsyncIterableDouble: Value.done should be true, got ${value.done}`);
+ is(entry.value, undefined, `AsyncIterableDouble: Entry.value should be ${undefined}, got ${entry.value}`);
+ is(entry.done, true, `AsyncIterableDouble: Entry.done should be true, got ${entry.done}`);
+
+ let idx = 0;
+ for await (let [itrkey, itrvalue] of itr) {
+ is(itrkey, elements[idx][0], `AsyncIterableDouble: Looping at ${idx} should have key ${elements[idx][0]}, got ${key}`);
+ is(itrvalue, elements[idx][1], `AsyncIterableDouble: Looping at ${idx} should have value ${elements[idx][1]}, got ${value}`);
+ ++idx;
+ }
+ is(idx, 3, `AsyncIterableDouble: Should have 3 loops of for-await-of, got ${idx}`);
+}
+
+async function test_data_double_union() {
+ info(`AsyncIterableDoubleUnion: Testing simple iterable creation and functionality`);
+
+ // eslint-disable-next-line no-undef
+ let itr = new TestInterfaceAsyncIterableDoubleUnion();
+ is(itr.entries, itr[Symbol.asyncIterator],
+ `AsyncIterableDoubleUnion: Should be using @@asyncIterator for 'entries'`);
+
+ let elements = [["long", 1], ["string", "a"]];
+ let key_itr = itr.keys();
+ let value_itr = itr.values();
+ let entries_itr = itr.entries();
+ let key = await key_itr.next();
+ let value = await value_itr.next();
+ let entry = await entries_itr.next();
+ for (let i = 0; i < 2; ++i) {
+ is(key.value, elements[i][0], `AsyncIterableDoubleUnion: Key.value should be ${elements[i][0]}, got ${key.value}`);
+ is(key.done, false, `AsyncIterableDoubleUnion: Key.done should be false, got ${key.done}`);
+ is(value.value, elements[i][1], `AsyncIterableDoubleUnion: Value.value should be ${elements[i][1]}, got ${value.value}`);
+ is(value.done, false, `AsyncIterableDoubleUnion: Value.done should be false, got ${value.done}`);
+ is(entry.value[0], elements[i][0], `AsyncIterableDoubleUnion: Entry.value[0] should be ${elements[i][0]}, got ${entry.value[0]}`);
+ is(entry.value[1], elements[i][1], `AsyncIterableDoubleUnion: Entry.value[1] should be ${elements[i][1]}, got ${entry.value[1]}`);
+ is(entry.done, false, `AsyncIterableDoubleUnion: Entry.done should be false, got ${entry.done}`);
+
+ key = await key_itr.next();
+ value = await value_itr.next();
+ entry = await entries_itr.next();
+ }
+ is(key.value, undefined, `AsyncIterableDoubleUnion: Key.value should be ${undefined}, got ${key.value}`);
+ is(key.done, true, `AsyncIterableDoubleUnion: Key.done should be true, got ${key.done}`);
+ is(value.value, undefined, `AsyncIterableDoubleUnion: Value.value should be ${undefined}, got ${value.value}`);
+ is(value.done, true, `AsyncIterableDoubleUnion: Value.done should be true, got ${value.done}`);
+ is(entry.value, undefined, `AsyncIterableDoubleUnion: Entry.value should be ${undefined}, got ${entry.value}`);
+ is(entry.done, true, `AsyncIterableDoubleUnion: Entry.done should be true, got ${entry.done}`);
+
+ let idx = 0;
+ for await (let [itrkey, itrvalue] of itr) {
+ is(itrkey, elements[idx][0], `AsyncIterableDoubleUnion: Looping at ${idx} should have key ${elements[idx][0]}, got ${key}`);
+ is(itrvalue, elements[idx][1], `AsyncIterableDoubleUnion: Looping at ${idx} should have value ${elements[idx][1]}, got ${value}`);
+ ++idx;
+ }
+ is(idx, 2, `AsyncIterableDoubleUnion: Should have 2 loops of for-await-of, got ${idx}`);
+}
+
+add_task(async function do_tests() {
+ await test_data_single();
+ await test_data_double();
+ await test_data_double_union();
+});
+
+ </script>
+ </body>
+</html>
diff --git a/dom/bindings/test/test_async_stacks.html b/dom/bindings/test/test_async_stacks.html
new file mode 100644
index 0000000000..fe761e783b
--- /dev/null
+++ b/dom/bindings/test/test_async_stacks.html
@@ -0,0 +1,109 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1148593
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1148593</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+ /* global noSuchFunction */
+
+ /** Test for Bug 1148593 **/
+
+ SimpleTest.waitForExplicitFinish();
+
+ var TESTS;
+
+ function nextTest() {
+ var t = TESTS.pop();
+ if (t) {
+ t();
+ } else {
+ SimpleTest.finish();
+ }
+ }
+
+ function checkStack(functionName) {
+ try {
+ noSuchFunction();
+ } catch (e) {
+ ok(e.stack.includes(functionName), "stack includes " + functionName);
+ }
+ nextTest();
+ }
+
+ function eventListener() {
+ checkStack("registerEventListener");
+ }
+ function registerEventListener(link) {
+ link.onload = eventListener;
+ }
+ function eventTest() {
+ var link = document.createElement("link");
+ link.rel = "stylesheet";
+ link.href = "data:text/css,";
+ registerEventListener(link);
+ document.body.appendChild(link);
+ }
+
+ function xhrListener() {
+ checkStack("xhrTest");
+ }
+ function xhrTest() {
+ var ourFile = location.href;
+ var x = new XMLHttpRequest();
+ x.onload = xhrListener;
+ x.open("get", ourFile, true);
+ x.send();
+ }
+
+ function rafListener() {
+ checkStack("rafTest");
+ }
+ function rafTest() {
+ requestAnimationFrame(rafListener);
+ }
+
+ var intervalId;
+ function intervalHandler() {
+ clearInterval(intervalId);
+ checkStack("intervalTest");
+ }
+ function intervalTest() {
+ intervalId = setInterval(intervalHandler, 5);
+ }
+
+ function postMessageHandler(ev) {
+ ev.stopPropagation();
+ checkStack("postMessageTest");
+ }
+ function postMessageTest() {
+ window.addEventListener("message", postMessageHandler, true);
+ window.postMessage("whatever", "*");
+ }
+
+ function runTests() {
+ TESTS = [postMessageTest, intervalTest, rafTest, xhrTest, eventTest];
+ nextTest();
+ }
+
+ addLoadEvent(function() {
+ SpecialPowers.pushPrefEnv(
+ {"set": [["javascript.options.asyncstack_capture_debuggee_only", false]]},
+ runTests);
+ });
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1148593">Mozilla Bug 1148593</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_attributes_on_types.html b/dom/bindings/test/test_attributes_on_types.html
new file mode 100644
index 0000000000..ce606d2014
--- /dev/null
+++ b/dom/bindings/test/test_attributes_on_types.html
@@ -0,0 +1,246 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1295322
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for WebIDL attributes on types</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=1295322">Mozilla Bug 1295322</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+ <script type="application/javascript">
+ /* global TestFunctions */
+
+ add_task(async function push_permission() {
+ await SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]});
+ });
+
+ add_task(function testClampedNullableOctet() {
+ let test = new TestFunctions();
+ test.clampedNullableOctet = null;
+ is(test.clampedNullableOctet, null, "clampedNullableOctet should be null");
+ test.clampedNullableOctet = -1;
+ is(test.clampedNullableOctet, 0, "clampedNullableOctet should be clamped to 0");
+ test.clampedNullableOctet = 256;
+ is(test.clampedNullableOctet, 255, "clampedNullableOctet should be clamped 255");
+ test.clampedNullableOctet = 200;
+ is(test.clampedNullableOctet, 200, "clampedNullableOctet should be 200");
+ test.clampedNullableOctet = null;
+ is(test.clampedNullableOctet, null, "clampedNullableOctet should be null");
+ });
+
+ add_task(function testEnforcedNullableOctet() {
+ let test = new TestFunctions();
+ test.enforcedNullableOctet = null;
+ is(test.enforcedNullableOctet, null, "enforcedNullableOctet should be null");
+ try {
+ test.enforcedNullableOctet = -1;
+ ok(false, "Setting -1 to enforcedNullableOctet should throw exception");
+ } catch(e) {}
+ is(test.enforcedNullableOctet, null, "enforcedNullableOctet should still be null");
+ try {
+ test.enforcedNullableOctet = 256;
+ ok(false, "Setting 256 to enforcedNullableOctet should throw exception");
+ } catch(e) {}
+ is(test.enforcedNullableOctet, null, "enforcedNullableOctet should still be null");
+ test.enforcedNullableOctet = 200;
+ is(test.enforcedNullableOctet, 200, "enforcedNullableOctet should be 200");
+ test.enforcedNullableOctet = null;
+ is(test.enforcedNullableOctet, null, "enforcedNullableOctet should be null");
+ });
+
+ add_task(function testAllowShared() {
+ let test = new TestFunctions();
+ [{type: "ArrayBuffer", isShared: false},
+ {type: "SharedArrayBuffer", isShared: true}].forEach(arrayBuffer => {
+ if (self[arrayBuffer.type] === undefined) {
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1606624
+ // Once we enable SharedArrayBuffer on all channel, we could remove
+ // this.
+ todo(false, `${arrayBuffer.type} is unavailable.`);
+ return;
+ }
+
+ let buffer = new self[arrayBuffer.type](32);
+ let threw = false;
+ // Test Not Allow Shared
+ try {
+ test.testNotAllowShared(buffer);
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ is(threw, arrayBuffer.isShared, `Call testNotAllowShared with ${arrayBuffer.type}`);
+
+ try {
+ test.testDictWithAllowShared({arrayBuffer: buffer});
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ is(threw, arrayBuffer.isShared, `Call testDictWithAllowShared with {arrayBuffer: ${arrayBuffer.type}}`);
+
+ try {
+ test.testUnionOfBuffferSource(buffer);
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ is(threw, arrayBuffer.isShared, `Call testUnionOfBuffferSource with ${arrayBuffer.type}`);
+
+ try {
+ test.arrayBuffer = buffer;
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ is(threw, arrayBuffer.isShared, `Set arrayBuffer to ${arrayBuffer.type}`);
+
+ try {
+ test.sequenceOfArrayBuffer = [buffer];
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ is(threw, arrayBuffer.isShared, `Set sequenceOfArrayBuffer to [${arrayBuffer.type}]`);
+
+ // Test Allow Shared
+ try {
+ test.testAllowShared(buffer);
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ ok(!threw, `Call testAllowShared with ${arrayBuffer.type}`);
+
+ try {
+ test.testDictWithAllowShared({allowSharedArrayBuffer: buffer});
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ ok(!threw, `Call testDictWithAllowShared with {allowSharedArrayBuffer: ${arrayBuffer.type}}`);
+
+ try {
+ test.testUnionOfAllowSharedBuffferSource(buffer);
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ ok(!threw, `Call testUnionOfAllowSharedBuffferSource with ${arrayBuffer.type}`);
+
+ try {
+ test.allowSharedArrayBuffer = buffer;
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ ok(!threw, `Set allowSharedArrayBuffer to ${arrayBuffer.type}`);
+
+ try {
+ test.sequenceOfAllowSharedArrayBuffer = [buffer];
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ ok(!threw, `Set sequenceOfAllowSharedArrayBuffer to [${arrayBuffer.type}]`);
+
+ ["Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array",
+ "Int32Array", "Uint32Array", "Float32Array", "Float64Array", "DataView"].forEach(arrayType => {
+ let array = new self[arrayType](buffer);
+ // Test Not Allow Shared
+ try {
+ test.testNotAllowShared(array);
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ is(threw, arrayBuffer.isShared, `Call testNotAllowShared with ${arrayType} (${arrayBuffer.type})`);
+
+ try {
+ test.testDictWithAllowShared({arrayBufferView: array});
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ is(threw, arrayBuffer.isShared, `Call testDictWithAllowShared with {arrayBufferView: ${arrayType} (${arrayBuffer.type})}`);
+
+ try {
+ test.testUnionOfBuffferSource(array);
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ is(threw, arrayBuffer.isShared, `Call testUnionOfBuffferSource with ${arrayType} (${arrayBuffer.type})`);
+
+ try {
+ test.arrayBufferView = array;
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ is(threw, arrayBuffer.isShared, `Set arrayBufferView to ${arrayType} (${arrayBuffer.type})`);
+
+ try {
+ test.sequenceOfArrayBufferView = [array];
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ is(threw, arrayBuffer.isShared, `Set sequenceOfArrayBufferView to [${arrayType} (${arrayBuffer.type})]`);
+
+ // Test Allow Shared
+ try {
+ test.testAllowShared(array);
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ ok(!threw, `Call testAllowShared with ${arrayType} (${arrayBuffer.type})`);
+
+ try {
+ test.testDictWithAllowShared({allowSharedArrayBufferView: array});
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ ok(!threw, `Call testDictWithAllowShared with {allowSharedArrayBufferView: ${arrayType} (${arrayBuffer.type})}`);
+
+ try {
+ test.testUnionOfAllowSharedBuffferSource(array);
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ ok(!threw, `Call testUnionOfAllowSharedBuffferSource with ${arrayType} (${arrayBuffer.type})`);
+
+ try {
+ test.allowSharedArrayBufferView = array;
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ ok(!threw, `Set allowSharedArrayBufferView to ${arrayType} (${arrayBuffer.type})`);
+
+ try {
+ test.sequenceOfAllowSharedArrayBufferView = [array];
+ threw = false;
+ } catch(e) {
+ threw = true;
+ }
+ ok(!threw, `Set sequenceOfAllowSharedArrayBufferView to [${arrayType} (${arrayBuffer.type})]`);
+ });
+ });
+ });
+ </script>
+</body>
+</html>
diff --git a/dom/bindings/test/test_barewordGetsWindow.html b/dom/bindings/test/test_barewordGetsWindow.html
new file mode 100644
index 0000000000..ddd62fc520
--- /dev/null
+++ b/dom/bindings/test/test_barewordGetsWindow.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=936056
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 936056</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 936056 **/
+ SimpleTest.waitForExplicitFinish();
+ window.onload = function() {
+ var desc = Object.getOwnPropertyDescriptor(frames[0], "document");
+ if (!desc || !desc.get) {
+ todo(false, "This test does nothing so far, but will once Window is on WebIDL bindings");
+ SimpleTest.finish();
+ return;
+ }
+ var get = desc.get;
+ ok(get, "Couldn't find document getter");
+ Object.defineProperty(frames[0], "foo", { get, configurable: true });
+
+ var barewordFunc = frames[0].eval("(function (count) { var doc; for (var i = 0; i < count; ++i) doc = foo; return doc.documentElement; })");
+ var qualifiedFunc = frames[0].eval("(function (count) { var doc; for (var i = 0; i < count; ++i) doc = window.document; return doc.documentElement; })");
+ document.querySelector("iframe").onload = function() {
+ // interp
+ is(barewordFunc(1).innerText, "OLD", "Bareword should see own inner 1");
+ is(qualifiedFunc(1).innerText, "NEW",
+ "Qualified should see current inner 1");
+ // baseline
+ is(barewordFunc(100).innerText, "OLD", "Bareword should see own inner 2");
+ is(qualifiedFunc(100).innerText, "NEW",
+ "Qualified should see current inner 2");
+ // ion
+ is(barewordFunc(10000).innerText, "OLD", "Bareword should see own inner 3");
+ is(qualifiedFunc(10000).innerText, "NEW",
+ "Qualified should see current inner 2");
+ SimpleTest.finish();
+ };
+ frames[0].location = "file_barewordGetsWindow_frame2.html";
+ };
+
+
+
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=936056">Mozilla Bug 936056</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe src="file_barewordGetsWindow_frame1.html"></iframe>
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_bug1036214.html b/dom/bindings/test/test_bug1036214.html
new file mode 100644
index 0000000000..8fbe373b65
--- /dev/null
+++ b/dom/bindings/test/test_bug1036214.html
@@ -0,0 +1,141 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1036214
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1036214</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+ /* global TestInterfaceJS */
+
+ /** Test for subsumes-checking |any| and |object| for js-implemented WebIDL. **/
+ SimpleTest.waitForExplicitFinish();
+ var xoObjects = [];
+ function setup() {
+ // window[0] is same-process and cross-origin, even with Fission enabled.
+ xoObjects.push(window[0]);
+ xoObjects.push(window[0].location);
+ xoObjects.push(SpecialPowers.unwrap(SpecialPowers.wrap(window[0]).document));
+ xoObjects.push(SpecialPowers.unwrap(SpecialPowers));
+ xoObjects.push(SpecialPowers.unwrap(SpecialPowers.wrap));
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]}, go);
+ }
+
+ function setup2() {
+ if (SpecialPowers.useRemoteSubframes) {
+ // window[1] is cross-origin and out of process, with Fission enabled.
+ xoObjects.push(window[1]);
+ xoObjects.push(window[1].location);
+ }
+ }
+
+ function checkThrows(f, msg) {
+ try {
+ f();
+ ok(false, "Should have thrown: " + msg);
+ } catch (e) {
+ ok(true, "Threw correctly: " + msg);
+ ok(/denied|insecure/.test(e), "Threw security exception: " + e);
+ }
+ }
+
+ function go() {
+ //
+ // Test the basics of the test interface.
+ //
+
+ var any = { a: 11 };
+ var obj = { b: 22, c: "str" };
+ var obj2 = { foo: "baz" };
+ var myDict = { anyMember: 42, objectMember: { answer: 42 }, objectOrStringMember: { answer: "anobject" },
+ anySequenceMember: [{}, 1, "thirdinsequence"],
+ objectRecordMember: { key: { answer: "fortytwo" } },
+ innerDictionary: { innerObject: { answer: "rabbithole" } } };
+ var t = new TestInterfaceJS(any, obj, myDict);
+ is(Object.getPrototypeOf(t), TestInterfaceJS.prototype, "Prototype setup works correctly");
+ is(t.anyArg, any, "anyArg is correct");
+ is(t.objectArg, obj, "objectArg is correct");
+ is(t.getDictionaryArg().anyMember, 42, "dictionaryArg looks correct");
+ is(t.getDictionaryArg().objectMember.answer, 42, "dictionaryArg looks correct");
+ is(t.getDictionaryArg().objectRecordMember.key.answer, "fortytwo", "dictionaryArg looks correct");
+ is(t.getDictionaryArg().objectRecordMember.key.answer, "fortytwo", "dictionaryArg looks correct");
+ t.anyAttr = 2;
+ is(t.anyAttr, 2, "ping-pong any attribute works");
+ t.objAttr = obj2;
+ is(t.objAttr, obj2, "ping-pong object attribute works");
+ t.setDictionaryAttr(myDict);
+ is(t.getDictionaryAttr().anyMember, 42, "ping-pong dictionary works");
+ is(t.getDictionaryAttr().objectMember.answer, 42, "ping-pong dictionary works");
+ is(t.getDictionaryAttr().objectRecordMember.key.answer, "fortytwo", "ping-pong dictionary works");
+ is(t.getDictionaryAttr().objectRecordMember.key.answer, "fortytwo", "ping-pong dictionary works");
+
+ is(any, t.pingPongAny(any), "ping-pong works with any");
+ is(obj, t.pingPongObject(obj), "ping-pong works with obj");
+ is(obj, t.pingPongObjectOrString(obj), "ping-pong works with obj or string");
+ is("foo", t.pingPongObjectOrString("foo"), "ping-pong works with obj or string");
+ is(t.pingPongDictionary(myDict).anyMember, 42, "ping pong works with dict");
+ is(t.pingPongDictionary(myDict).objectMember.answer, 42, "ping pong works with dict");
+ is(t.pingPongDictionary(myDict).objectOrStringMember.answer, "anobject", "ping pong works with dict");
+ is(t.pingPongDictionary(myDict).anySequenceMember[2], "thirdinsequence", "ping pong works with dict");
+ is(t.pingPongDictionary(myDict).objectRecordMember.key.answer, "fortytwo", "ping pong works with dict");
+ is(t.pingPongDictionary(myDict).objectRecordMember.key.answer, "fortytwo", "ping pong works with dict");
+ is(t.pingPongDictionary(myDict).innerDictionary.innerObject.answer, "rabbithole", "ping pong works with layered dicts");
+ is(t.pingPongDictionaryOrLong({anyMember: 42}), 42, "ping pong (dict or long) works with dict");
+ is(t.pingPongDictionaryOrLong(42), 42, "ping pong (dict or long) works with long");
+ ok(/canary/.test(t.pingPongRecord({ someVal: 42, someOtherVal: "canary" })), "ping pong works with record");
+ is(t.objectSequenceLength([{}, {}, {}]), 3, "ping pong works with object sequence");
+ is(t.anySequenceLength([42, "string", {}, undefined]), 4, "ping pong works with any sequence");
+
+ //
+ // Test that we throw in the cross-origin cases.
+ //
+
+ xoObjects.forEach(function(xoObj) {
+ new TestInterfaceJS();
+ checkThrows(() => new TestInterfaceJS(xoObj, undefined), "any param for constructor");
+ checkThrows(() => new TestInterfaceJS(undefined, xoObj), "obj param for constructor");
+ checkThrows(() => new TestInterfaceJS(undefined, undefined, { anyMember: xoObj }), "any dict param for constructor");
+ checkThrows(() => new TestInterfaceJS(undefined, undefined, { objectMember: xoObj }), "object dict param for constructor");
+ checkThrows(() => new TestInterfaceJS(undefined, undefined, { objectOrStringMember: xoObj }), "union dict param for constructor");
+ checkThrows(() => new TestInterfaceJS(undefined, undefined, { anySequenceMember: [0, xoObj, "hi" ] }), "sequence dict param for constructor");
+ checkThrows(() => new TestInterfaceJS(undefined, undefined, { innerDictionary: { innerObject: xoObj } }), "inner dict param for constructor");
+ checkThrows(() => t.anyAttr = xoObj, "anyAttr");
+ checkThrows(() => t.objectAttr = xoObj, "objAttr");
+ checkThrows(() => t.setDictionaryAttr({ anyMember: xoObj }), "dictionaryAttr any");
+ checkThrows(() => t.setDictionaryAttr({ objectMember: xoObj }), "dictionaryAttr object");
+ checkThrows(() => t.pingPongAny(xoObj), "pingpong any");
+ checkThrows(() => t.pingPongObject(xoObj), "pingpong obj");
+ checkThrows(() => t.pingPongObjectOrString(xoObj), "pingpong union");
+ checkThrows(() => t.pingPongDictionary({ anyMember: xoObj }), "dictionary pingpong any");
+ checkThrows(() => t.pingPongDictionary({ objectMember: xoObj }), "dictionary pingpong object");
+ checkThrows(() => t.pingPongDictionary({ anyMember: xoObj, objectMember: xoObj }), "dictionary pingpong both");
+ checkThrows(() => t.pingPongDictionary({ objectOrStringMember: xoObj }), "dictionary pingpong objectorstring");
+ checkThrows(() => t.pingPongDictionary({ objectRecordMember: { key: xoObj } }), "dictionary pingpong record of object");
+ checkThrows(() => t.pingPongDictionaryOrLong({ objectMember: xoObj }), "unionable dictionary");
+ checkThrows(() => t.pingPongDictionaryOrLong({ anyMember: xoObj }), "unionable dictionary");
+ checkThrows(() => t.pingPongRecord({ someMember: 42, someOtherMember: {}, crossOriginMember: xoObj }), "record");
+ checkThrows(() => t.objectSequenceLength([{}, {}, xoObj, {}]), "object sequence");
+ checkThrows(() => t.anySequenceLength([42, "someString", xoObj, {}]), "any sequence");
+ });
+
+
+ SimpleTest.finish();
+ }
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1036214">Mozilla Bug 1036214</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+<iframe id="ifr" onload="setup();" src="http://test1.mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe>
+<iframe id="ifr2" onload="setup2();" src="http://example.org/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe>
+</body>
+</html>
diff --git a/dom/bindings/test/test_bug1041646.html b/dom/bindings/test/test_bug1041646.html
new file mode 100644
index 0000000000..95550a98e2
--- /dev/null
+++ b/dom/bindings/test/test_bug1041646.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1041646
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1041646</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1041646 **/
+ // We need to reject the promise with a DOMException, so make sure we have
+ // something that produces one.
+ function throwException() {
+ document.createTextNode("").appendChild(document);
+ }
+ try {
+ throwException();
+ } catch (e) {
+ ok(e instanceof DOMException, "This test won't test what it should be testing");
+ }
+
+ SimpleTest.waitForExplicitFinish();
+
+ // We want a new DOMException each time here.
+ for (var i = 0; i < 100; ++i) {
+ new Promise(throwException);
+ }
+
+ // Now make sure we wait for all those promises above to reject themselves
+ Promise.resolve(1).then(function() {
+ SpecialPowers.gc(); // This should not assert or crash
+ SimpleTest.finish();
+ });
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1041646">Mozilla Bug 1041646</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_bug1123516_maplikesetlike.html b/dom/bindings/test/test_bug1123516_maplikesetlike.html
new file mode 100644
index 0000000000..bc5048eb05
--- /dev/null
+++ b/dom/bindings/test/test_bug1123516_maplikesetlike.html
@@ -0,0 +1,278 @@
+<!-- Any copyright is dedicated to the Public Domain.
+- http://creativecommons.org/publicdomain/zero/1.0/ -->
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Test Maplike Interface</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ </head>
+ <body>
+ <script class="testbody" type="application/javascript">
+ /* global TestInterfaceMaplike, TestInterfaceSetlike, TestInterfaceMaplikeObject, TestInterfaceMaplikeJSObject*/
+ SimpleTest.waitForExplicitFinish();
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]}, function() {
+ var base_properties = [["has", "function", 1],
+ ["entries", "function", 0],
+ ["keys", "function", 0],
+ ["values", "function", 0],
+ ["forEach", "function", 1],
+ ["size", "number"]];
+ var maplike_properties = base_properties.concat([["set", "function", 2]]);
+ var rw_properties = [["clear", "function", 0],
+ ["delete", "function", 1]];
+ var setlike_rw_properties = base_properties.concat(rw_properties).concat([["add", "function", 1]]);
+ var maplike_rw_properties = maplike_properties.concat(rw_properties).concat([["get", "function", 1]]);
+ var testExistence = function testExistence(prefix, obj, properties) {
+ for (var [name, type, args] of properties) {
+ // Properties are somewhere up the proto chain, hasOwnProperty won't work
+ isnot(obj[name], undefined,
+ `${prefix} object has property ${name}`);
+
+ is(typeof obj[name], type,
+ `${prefix} object property ${name} is a ${type}`);
+ // Check function length
+ if (type == "function") {
+ is(obj[name].length, args,
+ `${prefix} object property ${name} is length ${args}`);
+ is(obj[name].name, name,
+ `${prefix} object method name is ${name}`);
+ }
+
+ // Find where property is on proto chain, check for enumerablility there.
+ var owner = obj;
+ while (owner) {
+ var propDesc = Object.getOwnPropertyDescriptor(owner, name);
+ if (propDesc) {
+ ok(propDesc.enumerable,
+ `${prefix} object property ${name} should be enumerable`);
+ break;
+ }
+ owner = Object.getPrototypeOf(owner);
+ }
+ }
+ };
+
+ var m;
+ var testSet;
+ var testIndex;
+
+ // Simple map creation and functionality test
+ info("SimpleMap: Testing simple map creation and functionality");
+ m = new TestInterfaceMaplike();
+ ok(m, "SimpleMap: got a TestInterfaceMaplike object");
+ testExistence("SimpleMap: ", m, maplike_rw_properties);
+ is(m.size, 0, "SimpleMap: size should be zero");
+ ok(!m.has("test"), "SimpleMap: maplike has should return false");
+ is(m.get("test"), undefined, "SimpleMap: maplike get should return undefined on bogus lookup");
+ var m1 = m.set("test", 1);
+ is(m, m1, "SimpleMap: return from set should be map object");
+ is(m.size, 1, "SimpleMap: size should be 1");
+ ok(m.has("test"), "SimpleMap: maplike has should return true");
+ is(m.get("test"), 1, "SimpleMap: maplike get should return value entered");
+ m.set("test2", 2);
+ is(m.size, 2, "SimpleMap: size should be 2");
+ testSet = [["test", 1], ["test2", 2]];
+ testIndex = 0;
+ m.forEach(function(v, k, o) {
+ "use strict";
+ is(o, m, "SimpleMap: foreach obj is correct");
+ is(k, testSet[testIndex][0], "SimpleMap: foreach map key: " + k + " = " + testSet[testIndex][0]);
+ is(v, testSet[testIndex][1], "SimpleMap: foreach map value: " + v + " = " + testSet[testIndex][1]);
+ testIndex += 1;
+ });
+ is(testIndex, 2, "SimpleMap: foreach ran correct number of times");
+ ok(m.has("test2"), "SimpleMap: maplike has should return true");
+ is(m.get("test2"), 2, "SimpleMap: maplike get should return value entered");
+ is(m.delete("test2"), true, "SimpleMap: maplike deletion should return boolean");
+ is(m.size, 1, "SimpleMap: size should be 1");
+ var iterable = false;
+ for (let e of m) {
+ iterable = true;
+ is(e[0], "test", "SimpleMap: iterable first array element should be key");
+ is(e[1], 1, "SimpleMap: iterable second array element should be value");
+ }
+ is(m[Symbol.iterator].length, 0, "SimpleMap: @@iterator symbol is correct length");
+ is(m[Symbol.iterator].name, "entries", "SimpleMap: @@iterator symbol has correct name");
+ is(m[Symbol.iterator], m.entries, 'SimpleMap: @@iterator is an alias for "entries"');
+ ok(iterable, "SimpleMap: @@iterator symbol resolved correctly");
+ for (let k of m.keys()) {
+ is(k, "test", "SimpleMap: first keys element should be 'test'");
+ }
+ for (let v of m.values()) {
+ is(v, 1, "SimpleMap: first values elements should be 1");
+ }
+ for (let e of m.entries()) {
+ is(e[0], "test", "SimpleMap: entries first array element should be 'test'");
+ is(e[1], 1, "SimpleMap: entries second array element should be 1");
+ }
+ m.clear();
+ is(m.size, 0, "SimpleMap: size should be 0 after clear");
+
+ // Simple set creation and functionality test
+ info("SimpleSet: Testing simple set creation and functionality");
+ m = new TestInterfaceSetlike();
+ ok(m, "SimpleSet: got a TestInterfaceSetlike object");
+ testExistence("SimpleSet: ", m, setlike_rw_properties);
+ is(m.size, 0, "SimpleSet: size should be zero");
+ ok(!m.has("test"), "SimpleSet: maplike has should return false");
+ m1 = m.add("test");
+ is(m, m1, "SimpleSet: return from set should be map object");
+ is(m.size, 1, "SimpleSet: size should be 1");
+ ok(m.has("test"), "SimpleSet: maplike has should return true");
+ m.add("test2");
+ is(m.size, 2, "SimpleSet: size should be 2");
+ testSet = ["test", "test2"];
+ testIndex = 0;
+ m.forEach(function(v, k, o) {
+ "use strict";
+ is(o, m, "SimpleSet: foreach obj is correct");
+ is(k, testSet[testIndex], "SimpleSet: foreach set key: " + k + " = " + testSet[testIndex]);
+ testIndex += 1;
+ });
+ is(testIndex, 2, "SimpleSet: foreach ran correct number of times");
+ ok(m.has("test2"), "SimpleSet: maplike has should return true");
+ is(m.delete("test2"), true, "SimpleSet: maplike deletion should return true");
+ is(m.size, 1, "SimpleSet: size should be 1");
+ iterable = false;
+ for (let e of m) {
+ iterable = true;
+ is(e, "test", "SimpleSet: iterable first array element should be key");
+ }
+ is(m[Symbol.iterator].length, 0, "SimpleSet: @@iterator symbol is correct length");
+ is(m[Symbol.iterator].name, "values", "SimpleSet: @@iterator symbol has correct name");
+ is(m[Symbol.iterator], m.values, 'SimpleSet: @@iterator is an alias for "values"');
+ ok(iterable, "SimpleSet: @@iterator symbol resolved correctly");
+ for (let k of m.keys()) {
+ is(k, "test", "SimpleSet: first keys element should be 'test'");
+ }
+ for (let v of m.values()) {
+ is(v, "test", "SimpleSet: first values elements should be 'test'");
+ }
+ for (let e of m.entries()) {
+ is(e[0], "test", "SimpleSet: Entries first array element should be 'test'");
+ is(e[1], "test", "SimpleSet: Entries second array element should be 'test'");
+ }
+ m.clear();
+ is(m.size, 0, "SimpleSet: size should be 0 after clear");
+
+ // Map convenience function test
+ info("Testing map convenience functions");
+ m = new TestInterfaceMaplike();
+ ok(m, "MapConvenience: got a TestInterfaceMaplike object");
+ is(m.size, 0, "MapConvenience: size should be zero");
+ ok(!m.hasInternal("test"), "MapConvenience: maplike hasInternal should return false");
+ // It's fine to let getInternal to return 0 if the key doesn't exist
+ // because this API can only be used internally in C++ and we'd throw
+ // an error if the key doesn't exist.
+ SimpleTest.doesThrow(() => m.getInternal("test"), 0, "MapConvenience: maplike getInternal should throw if the key doesn't exist");
+ m.setInternal("test", 1);
+ is(m.size, 1, "MapConvenience: size should be 1");
+ ok(m.hasInternal("test"), "MapConvenience: maplike hasInternal should return true");
+ is(m.get("test"), 1, "MapConvenience: maplike get should return value entered");
+ is(m.getInternal("test"), 1, "MapConvenience: maplike getInternal should return value entered");
+ m.setInternal("test2", 2);
+ is(m.size, 2, "size should be 2");
+ ok(m.hasInternal("test2"), "MapConvenience: maplike hasInternal should return true");
+ is(m.get("test2"), 2, "MapConvenience: maplike get should return value entered");
+ is(m.getInternal("test2"), 2, "MapConvenience: maplike getInternal should return value entered");
+ is(m.deleteInternal("test2"), true, "MapConvenience: maplike deleteInternal should return true");
+ is(m.size, 1, "MapConvenience: size should be 1");
+ m.clearInternal();
+ is(m.size, 0, "MapConvenience: size should be 0 after clearInternal");
+
+ // Map convenience function test using objects and readonly
+
+ info("Testing Map convenience function test using objects and readonly");
+ m = new TestInterfaceMaplikeObject();
+ ok(m, "ReadOnlyMapConvenience: got a TestInterfaceMaplikeObject object");
+ is(m.size, 0, "ReadOnlyMapConvenience: size should be zero");
+ is(m.set, undefined, "ReadOnlyMapConvenience: readonly map, should be no set function");
+ is(m.clear, undefined, "ReadOnlyMapConvenience: readonly map, should be no clear function");
+ is(m.delete, undefined, "ReadOnlyMapConvenience: readonly map, should be no delete function");
+ ok(!m.hasInternal("test"), "ReadOnlyMapConvenience: maplike hasInternal should return false");
+ SimpleTest.doesThrow(() => m.getInternal("test"), "ReadOnlyMapConvenience: maplike getInternal should throw when the key doesn't exist");
+ m.setInternal("test");
+ is(m.size, 1, "size should be 1");
+ ok(m.hasInternal("test"), "ReadOnlyMapConvenience: maplike hasInternal should return true");
+ ok(m.getInternal("test") instanceof TestInterfaceMaplike, "ReadOnlyMapConvenience: maplike getInternal should return the object");
+ m.setInternal("test2");
+ is(m.size, 2, "size should be 2");
+ ok(m.hasInternal("test2"), "ReadOnlyMapConvenience: maplike hasInternal should return true");
+ ok(m.getInternal("test2") instanceof TestInterfaceMaplike, "ReadOnlyMapConvenience: maplike getInternal should return the object");
+ is(m.deleteInternal("test2"), true, "ReadOnlyMapConvenience: maplike deleteInternal should return true");
+ is(m.size, 1, "ReadOnlyMapConvenience: size should be 1");
+ m.clearInternal();
+ is(m.size, 0, "ReadOnlyMapConvenience: size should be 0 after clearInternal");
+
+ // Map convenience function test using JavaScript objects
+ info("Testing Map convenience function test using javascript objects");
+ m = new TestInterfaceMaplikeJSObject();
+ ok(m, "JSObjectMapConvenience: got a TestInterfaceMaplikeJSObject object");
+ is(m.size, 0, "JSObjectMapConvenience: size should be zero");
+ is(m.set, undefined, "JSObjectMapConvenience: readonly map, should be no set function");
+ is(m.clear, undefined, "JSObjectMapConvenience: readonly map, should be no clear function");
+ is(m.delete, undefined, "JSObjectMapConvenience: readonly map, should be no delete function");
+ ok(!m.hasInternal("test"), "JSObjectMapConvenience: maplike hasInternal should return false");
+ SimpleTest.doesThrow(() => m.getInternal("test"), "JSObjectMapConvenience: maplike getInternal should throw when the key doesn't exist");
+ let testObject = {"Hey1": 1};
+ m.setInternal("test", testObject);
+ is(m.size, 1, "size should be 1");
+ ok(m.hasInternal("test"), "JSObjectMapConvenience: maplike hasInternal should return true");
+ let addedObject = m.getInternal("test");
+ is(addedObject, testObject, "JSObjectMapConvenience: maplike getInternal should return the object");
+ testObject = {"Hey2": 2};
+ m.setInternal("test2", testObject);
+ is(m.size, 2, "size should be 2");
+ ok(m.hasInternal("test2"), "JSObjectMapConvenience: maplike hasInternal should return true");
+ addedObject = m.getInternal("test2");
+ is(addedObject, testObject, "JSObjectMapConvenience: maplike getInternal should return the object");
+ is(m.deleteInternal("test2"), true, "JSObjectMapConvenience: maplike deleteInternal should return true");
+ is(m.size, 1, "JSObjectMapConvenience: size should be 1");
+ m.clearInternal();
+ is(m.size, 0, "JSObjectMapConvenience: size should be 0 after clearInternal");
+ // JS implemented map creation convenience function test
+
+ // Test this override for forEach
+ info("ForEachThisOverride: Testing this override for forEach");
+ m = new TestInterfaceMaplike();
+ m.set("test", 1);
+ m.forEach(function(v, k, o) {
+ "use strict";
+ is(o, m, "ForEachThisOverride: foreach obj is correct");
+ is(this, 5, "ForEachThisOverride: 'this' value should be correct");
+ }, 5);
+
+ // Test defaulting arguments on maplike to undefined
+ info("MapArgsDefault: Testing maplike defaulting arguments to undefined");
+ m = new TestInterfaceMaplike();
+ m.set();
+ is(m.size, 1, "MapArgsDefault: should have 1 entry");
+ m.forEach(function(v, k) {
+ "use strict";
+ is(typeof k, "string", "MapArgsDefault: key is a string");
+ is(k, "undefined", "MapArgsDefault: key is the string undefined");
+ is(v, 0, "MapArgsDefault: value is 0");
+ });
+ is(m.get(), 0, "MapArgsDefault: no argument to get() returns correct value");
+ m.delete();
+ is(m.size, 0, "MapArgsDefault: should have 0 entries");
+
+ // Test defaulting arguments on setlike to undefined
+ info("SetArgsDefault: Testing setlike defaulting arguments to undefined");
+ m = new TestInterfaceSetlike();
+ m.add();
+ is(m.size, 1, "SetArgsDefault: should have 1 entry");
+ m.forEach(function(v, k) {
+ "use strict";
+ is(typeof k, "string", "SetArgsDefault: key is a string");
+ is(k, "undefined", "SetArgsDefault: key is the string undefined");
+ });
+ m.delete();
+ is(m.size, 0, "SetArgsDefault: should have 0 entries");
+
+ SimpleTest.finish();
+ });
+ </script>
+ </body>
+</html>
diff --git a/dom/bindings/test/test_bug1123516_maplikesetlikechrome.xhtml b/dom/bindings/test/test_bug1123516_maplikesetlikechrome.xhtml
new file mode 100644
index 0000000000..724c40cbd3
--- /dev/null
+++ b/dom/bindings/test/test_bug1123516_maplikesetlikechrome.xhtml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
+<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1123516
+-->
+<window title="Mozilla Bug 1123516"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <iframe id="t"></iframe>
+
+ <!-- test results are displayed in the html:body -->
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1123516"
+ target="_blank">Mozilla Bug 1123516</a>
+ </body>
+
+ <!-- test code goes here -->
+ <script type="application/javascript">
+ <![CDATA[
+ /* global TestInterfaceSetlikeNode */
+
+ /** Test for Bug 1123516 **/
+ function doTest() {
+ var win = $("t").contentWindow;
+ var sandbox = Cu.Sandbox(win, { sandboxPrototype: win });
+ is(sandbox._content, undefined, "_content does nothing over Xray");
+ // Test cross-compartment usage of maplike/setlike WebIDL structures.
+ SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, function() {
+ try {
+ var maplike = Cu.evalInSandbox("var m = new TestInterfaceMaplike(); m;", sandbox);
+ maplike.set("test2", 2);
+ is(maplike.get("test2"), 2, "Should be able to create and use maplike/setlike across compartments");
+ var test = Cu.evalInSandbox("m.get('test2');", sandbox);
+ is(test, 2, "Maplike/setlike should still work in original compartment");
+ is(maplike.size, 1, "Testing size retrieval across compartments");
+ } catch(e) {
+ ok(false, "Shouldn't throw when working with cross-compartment maplike/setlike interfaces " + e)
+ };
+ try {
+ var setlike = Cu.evalInSandbox("var m = new TestInterfaceSetlikeNode(); m.add(document.documentElement); m;", sandbox);
+ is(TestInterfaceSetlikeNode.prototype.has.call(setlike, win.document.documentElement), true,
+ "Cross-compartment unwrapping/comparison has works");
+ // TODO: Should throw until iterators are handled by Xrays, Bug 1023984
+ try {
+ TestInterfaceSetlikeNode.prototype.keys.call(setlike);
+ ok(false, "Calling iterators via xrays should fail");
+ /* eslint-disable-next-line no-shadow */
+ } catch(e) {
+ ok(true, "Calling iterators via xrays should fail");
+ }
+
+ setlike.forEach((v,k,t) => { is(v, win.document.documentElement, "Cross-compartment forEach works"); });
+ TestInterfaceSetlikeNode.prototype.forEach.call(setlike,
+ (v,k,t) => { is(v, win.document.documentElement, "Cross-compartment forEach works"); });
+ is(TestInterfaceSetlikeNode.prototype.delete.call(setlike, win.document.documentElement), true,
+ "Cross-compartment unwrapping/comparison delete works");
+ /* eslint-disable-next-line no-shadow */
+ } catch(e) {
+ ok(false, "Shouldn't throw when working with cross-compartment maplike/setlike interfaces " + e)
+ };
+ SimpleTest.finish();
+ });
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addLoadEvent(doTest);
+ ]]>
+ </script>
+</window>
diff --git a/dom/bindings/test/test_bug1123875.html b/dom/bindings/test/test_bug1123875.html
new file mode 100644
index 0000000000..383d14fe9f
--- /dev/null
+++ b/dom/bindings/test/test_bug1123875.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test for Bug 1123875</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+/* global test, assert_throws */
+ test(() => {
+ assert_throws(new TypeError, () => {
+ "use strict";
+ document.childNodes.length = 0;
+ });
+ }, "setting a readonly attribute on a proxy in strict mode should throw a TypeError");
+</script>
diff --git a/dom/bindings/test/test_bug1287912.html b/dom/bindings/test/test_bug1287912.html
new file mode 100644
index 0000000000..310a53afc6
--- /dev/null
+++ b/dom/bindings/test/test_bug1287912.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1287912
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1287912</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1287912">Mozilla Bug 1287912</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe id="t" src="http://example.org/tests/dom/bindings/test/"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+function test() {
+ var win = document.getElementById("t").contentWindow;
+ is(Object.getPrototypeOf(win.Image), win.Function.prototype, "The __proto__ of a named constructor is Function.prototype");
+ is(win.Image.prototype, win.HTMLImageElement.prototype, "The prototype property of a named constructor is the interface prototype object");
+ is(win.HTMLImageElement.foo, undefined, "Should not have a property named foo on the HTMLImageElement interface object");
+ is(win.Image.foo, undefined, "Should not have a property named foo on the Image named constructor");
+
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(test);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_bug1457051.html b/dom/bindings/test/test_bug1457051.html
new file mode 100644
index 0000000000..2ed1bd16ec
--- /dev/null
+++ b/dom/bindings/test/test_bug1457051.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1457051
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1457051</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://global/skin"/>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1457051 **/
+ ok(Element.isInstance(document.documentElement), "Basic isInstance works");
+ ok(!Element.isInstance(null),
+ "Passing null should return false without throwing");
+ ok(!Element.isInstance(5), "Passing 5 should return false without throwing");
+ var obj = Object.create(Element.prototype);
+ ok(obj instanceof Element, "instanceof should walk the proto chain");
+ ok(!Element.isInstance(obj), "isInstance should be a pure brand check");
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1457051">Mozilla Bug 1457051</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_bug1808352.html b/dom/bindings/test/test_bug1808352.html
new file mode 100644
index 0000000000..aa1dc133b8
--- /dev/null
+++ b/dom/bindings/test/test_bug1808352.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test for Bug 1808352</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<div id=log></div>
+<div id="testnode"></div>
+<script>
+function loadedFrame() {
+ var node = document.getElementById("testnode");
+ var frame = document.getElementById("frame");
+ frame.contentWindow.document.adoptNode(node);
+ document.adoptNode(node);
+ var res;
+ // Use a loop to ensure the JITs optimize the `id` getter access.
+ for (var i = 0; i < 10_000; i++) {
+ res = node.id;
+ }
+ is(res, "testnode", "expected node id");
+ SimpleTest.finish();
+}
+SimpleTest.waitForExplicitFinish();
+document.domain = "mochi.test"; // We want a cross-compartment adoptNode.
+</script>
+<iframe id="frame" src="http://test1.mochi.test:8888/tests/dom/bindings/test/file_bug1808352_frame.html"></iframe>
diff --git a/dom/bindings/test/test_bug1808352b.html b/dom/bindings/test/test_bug1808352b.html
new file mode 100644
index 0000000000..c3b95f62f9
--- /dev/null
+++ b/dom/bindings/test/test_bug1808352b.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test for Bug 1808352</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<div id=log></div>
+<div id="testnode"></div>
+<script>
+var w;
+function loadedFrame() {
+ var node = document.getElementById("testnode");
+ w.document.adoptNode(node);
+ document.adoptNode(node);
+ var res;
+ // Use a loop to ensure the JITs optimize the `id` getter access.
+ for (var i = 0; i < 10_000; i++) {
+ res = node.id;
+ }
+ is(res, "testnode", "expected node id");
+ w.close();
+ SimpleTest.finish();
+}
+SimpleTest.waitForExplicitFinish();
+// Open a popup window, so it'll be same origin, but cross compartment.
+w = window.open("file_bug1808352b_frame.html", "_blank");
+</script>
diff --git a/dom/bindings/test/test_bug560072.html b/dom/bindings/test/test_bug560072.html
new file mode 100644
index 0000000000..de2f8baec9
--- /dev/null
+++ b/dom/bindings/test/test_bug560072.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=560072
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 560072</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=560072">Mozilla Bug 560072</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 560072 **/
+is(document.body,
+ Object.getOwnPropertyDescriptor(Document.prototype, "body").get.call(document),
+ "Should get body out of property descriptor");
+
+is(document.body,
+ Object.getOwnPropertyDescriptor(
+ Object.getPrototypeOf(Object.getPrototypeOf(document)), "body").get.call(document),
+ "Should get body out of property descriptor this way too");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_bug742191.html b/dom/bindings/test/test_bug742191.html
new file mode 100644
index 0000000000..f991bf6f91
--- /dev/null
+++ b/dom/bindings/test/test_bug742191.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=742191
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for invalid argument object</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=742191">Mozilla Bug 742191</a>
+<p id="display"></p>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 742191 **/
+function doTest() {
+ var gotTypeError = false;
+ var ctx = document.createElement("canvas").getContext("2d");
+ try {
+ ctx.drawImage({}, 0, 0);
+ } catch (e) {
+ if (e instanceof TypeError) {
+ gotTypeError = true;
+ }
+ }
+
+ ok(gotTypeError, "passing an invalid argument should cause a type error!");
+}
+doTest();
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_bug759621.html b/dom/bindings/test/test_bug759621.html
new file mode 100644
index 0000000000..7c47887d35
--- /dev/null
+++ b/dom/bindings/test/test_bug759621.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=759621
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 759621</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=759621">Mozilla Bug 759621</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 759621 **/
+var l = document.getElementsByTagName("*");
+l.namedItem = "pass";
+is(l.namedItem, "pass", "Should be able to set expando shadowing a proto prop");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_bug773326.html b/dom/bindings/test/test_bug773326.html
new file mode 100644
index 0000000000..cb21ae6916
--- /dev/null
+++ b/dom/bindings/test/test_bug773326.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test for Bug 773326</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+/* global test */
+
+test(function() {
+ new Worker("data:text/javascript,new XMLHttpRequest(42)");
+}, "Should not crash");
+</script>
diff --git a/dom/bindings/test/test_bug775543.html b/dom/bindings/test/test_bug775543.html
new file mode 100644
index 0000000000..d8fe8aaf2b
--- /dev/null
+++ b/dom/bindings/test/test_bug775543.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=775543
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 775543</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=775543">Mozilla Bug 775543</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe id="t" src="http://example.org/tests/dom/bindings/test/file_bug775543.html" onload="test();"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+/* global XPCNativeWrapper */
+/** Test for Bug 775543 **/
+
+function test() {
+ var a = XPCNativeWrapper(document.getElementById("t").contentWindow.wrappedJSObject.worker);
+ isnot(XPCNativeWrapper.unwrap(a), a, "XPCNativeWrapper(Worker) should be an Xray wrapper");
+ a.toString();
+ ok(true, "Shouldn't crash when calling a method on an Xray wrapper around a worker");
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_bug788369.html b/dom/bindings/test/test_bug788369.html
new file mode 100644
index 0000000000..02d03ac199
--- /dev/null
+++ b/dom/bindings/test/test_bug788369.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=788369
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 788369</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=788369">Mozilla Bug 788369</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 788369 **/
+try {
+ var xhr = new (window.ActiveXObject || XMLHttpRequest)("Microsoft.XMLHTTP");
+ ok(xhr instanceof XMLHttpRequest, "Should have an XHR object");
+} catch (e) {
+ ok(false, "Should not throw exception when constructing: " + e);
+}
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_bug852846.html b/dom/bindings/test/test_bug852846.html
new file mode 100644
index 0000000000..19ec39dae5
--- /dev/null
+++ b/dom/bindings/test/test_bug852846.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=852846
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 852846</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 852846 **/
+ var elem = document.createElement("div");
+ is(elem.style.color, "", "Shouldn't have color set on HTML element");
+ elem.style = "color: green";
+ is(elem.style.color, "green", "Should have color set on HTML element");
+
+ elem = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+ is(elem.style.color, "", "Shouldn't have color set on SVG element");
+ elem.style = "color: green";
+ is(elem.style.color, "green", "Should have color set on SVG element");
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=852846">Mozilla Bug 852846</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_bug862092.html b/dom/bindings/test/test_bug862092.html
new file mode 100644
index 0000000000..871252660a
--- /dev/null
+++ b/dom/bindings/test/test_bug862092.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=862092
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 862092</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 862092 **/
+
+ SimpleTest.waitForExplicitFinish();
+ function runTest() {
+ var frameDoc = document.getElementById("f").contentDocument;
+ var a = document.createElement("select");
+ a.expando = "test";
+ a = frameDoc.adoptNode(a);
+ is(a.expando, "test", "adoptNode needs to preserve expandos");
+ SimpleTest.finish();
+ }
+
+ </script>
+</head>
+<body onload="runTest();">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=862092">Mozilla Bug 862092</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe id="f"></iframe>
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_callback_across_document_open.html b/dom/bindings/test/test_callback_across_document_open.html
new file mode 100644
index 0000000000..dee4445904
--- /dev/null
+++ b/dom/bindings/test/test_callback_across_document_open.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Test for callback invocation for a callback that comes from a
+ no-longer-current window that still has an active document.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<iframe srcdoc='<script>function f() { parent.callCount++; }</script>'></iframe>
+<script>
+/* global async_test, assert_equals */
+ var callCount = 0;
+ var t = async_test("A test of callback invocation in a no-longer-current window with a still-active document");
+ window.addEventListener("load", t.step_func_done(function() {
+ var d = document.createElement("div");
+ d.addEventListener("xyz", frames[0].f);
+ frames[0].document.open();
+ frames[0].document.write("All gone");
+ frames[0].document.close();
+ d.dispatchEvent(new Event("xyz"));
+ assert_equals(callCount, 1, "Callback should have been called");
+ }));
+</script>
diff --git a/dom/bindings/test/test_callback_default_thisval.html b/dom/bindings/test/test_callback_default_thisval.html
new file mode 100644
index 0000000000..337657b21f
--- /dev/null
+++ b/dom/bindings/test/test_callback_default_thisval.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=957929
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 957929</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 957929 **/
+ SimpleTest.waitForExplicitFinish();
+
+ function f() {
+ "use strict";
+ is(this, undefined, "Should have undefined this value");
+ SimpleTest.finish();
+ }
+
+ addLoadEvent(function() {
+ requestAnimationFrame(f);
+ });
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=957929">Mozilla Bug 957929</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_callback_exceptions.html b/dom/bindings/test/test_callback_exceptions.html
new file mode 100644
index 0000000000..93d4787774
--- /dev/null
+++ b/dom/bindings/test/test_callback_exceptions.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Test for ...</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+/* global promise_test, promise_rejects */
+
+promise_test(function(t) {
+ var iterator = document.createNodeIterator(document, NodeFilter.SHOW_ALL, JSON.parse);
+ return promise_rejects(t, new SyntaxError,
+ Promise.resolve().then(iterator.nextNode.bind(iterator)));
+}, "Trying to use JSON.parse as filter should throw a catchable SyntaxError exception even when the filter is invoked async");
+
+promise_test(function(t) {
+ return promise_rejects(t, new SyntaxError, Promise.resolve("{").then(JSON.parse));
+}, "Trying to use JSON.parse as a promise callback should allow the next promise to handle the resulting exception.");
+</script>
diff --git a/dom/bindings/test/test_cloneAndImportNode.html b/dom/bindings/test/test_cloneAndImportNode.html
new file mode 100644
index 0000000000..4acfec82cd
--- /dev/null
+++ b/dom/bindings/test/test_cloneAndImportNode.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=882541
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 882541</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 882541 **/
+ var div = document.createElement("div");
+ div.appendChild(document.createElement("span"));
+
+ var div2;
+
+ div2 = div.cloneNode();
+ is(div2.childNodes.length, 0, "cloneNode() should do a shallow clone");
+
+ div2 = div.cloneNode(undefined);
+ is(div2.childNodes.length, 0, "cloneNode(undefined) should do a shallow clone");
+
+ div2 = div.cloneNode(true);
+ is(div2.childNodes.length, 1, "cloneNode(true) should do a deep clone");
+
+ div2 = document.importNode(div);
+ is(div2.childNodes.length, 0, "importNode(node) should do a deep import");
+
+ div2 = document.importNode(div, undefined);
+ is(div2.childNodes.length, 0, "importNode(undefined) should do a shallow import");
+
+ div2 = document.importNode(div, true);
+ is(div2.childNodes.length, 1, "importNode(true) should do a deep import");
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=882541">Mozilla Bug 882541</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_crossOriginWindowSymbolAccess.html b/dom/bindings/test/test_crossOriginWindowSymbolAccess.html
new file mode 100644
index 0000000000..0ece6c8f9d
--- /dev/null
+++ b/dom/bindings/test/test_crossOriginWindowSymbolAccess.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Test for accessing symbols on a cross-origin window</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<iframe id="sameProc" src="http://test1.mochi.test:8888/tests/js/xpconnect/tests/mochitest/file_empty.html"></iframe>
+<iframe id="crossProc" src="http://www1.w3c-test.org/common/blank.html"></iframe>
+<script>
+/* global async_test, assert_equals, assert_throws */
+
+async_test(function(t) {
+ window.addEventListener("load", t.step_func(
+ function() {
+ assert_equals(document.getElementById("sameProc").contentDocument, null, "Should have a crossorigin frame");
+ assert_equals(document.getElementById("crossProc").contentDocument, null, "Should have a crossorigin frame");
+ for (let f of [0, 1]) {
+ assert_throws("SecurityError", function() {
+ frames[f][Symbol.iterator];
+ }, "Should throw exception on cross-origin Window symbol-named get");
+ assert_throws("SecurityError", function() {
+ frames[f].location[Symbol.iterator];
+ }, "Should throw exception on cross-origin Location symbol-named get");
+ }
+ t.done();
+ }
+ ));
+}, "Check Symbol access on load");
+</script>
diff --git a/dom/bindings/test/test_defineProperty.html b/dom/bindings/test/test_defineProperty.html
new file mode 100644
index 0000000000..391c6fcac8
--- /dev/null
+++ b/dom/bindings/test/test_defineProperty.html
@@ -0,0 +1,157 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=910220
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 910220</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=910220">Mozilla Bug 910220</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<form name="x"></form>
+</div>
+<pre id="test">
+</pre>
+<script type="application/javascript">
+
+/** Test for Bug 910220 **/
+
+function getX() {
+ return "x";
+}
+
+function namedSetStrict(obj) {
+ "use strict";
+ var threw;
+ try {
+ obj.x = 5;
+ threw = false;
+ } catch (e) {
+ threw = true;
+ }
+ ok(threw,
+ "Should throw in strict mode when setting named property on " + obj);
+
+ try {
+ obj[getX()] = 5;
+ threw = false;
+ } catch (e) {
+ threw = true;
+ }
+ ok(threw,
+ "Should throw in strict mode when setting named property via SETELEM on " + obj);
+
+ try {
+ Object.defineProperty(obj, "x", { value: 17 });
+ threw = false;
+ } catch (e) {
+ threw = true;
+ }
+ ok(threw,
+ "Should throw in strict mode when defining named property on " + obj);
+}
+function namedSetNonStrict(obj) {
+ var threw;
+ try {
+ obj.x = 5;
+ threw = false;
+ } catch (e) {
+ threw = true;
+ }
+ ok(!threw,
+ "Should not throw in non-strict mode when setting named property on " + obj);
+
+ try {
+ obj[getX()] = 5;
+ threw = false;
+ } catch (e) {
+ threw = true;
+ }
+ ok(!threw,
+ "Should not throw in non-strict mode when setting named property via SETELEM on" + obj);
+
+ try {
+ Object.defineProperty(obj, "x", { value: 17 });
+ threw = false;
+ } catch (e) {
+ threw = true;
+ }
+ ok(threw,
+ "Should throw in non-strict mode when defining named property on " + obj);
+}
+for (let obj of [ document, document.forms ]) {
+ namedSetStrict(obj);
+ namedSetNonStrict(obj);
+}
+
+function indexedSetStrict(obj) {
+ "use strict";
+ var threw;
+ try {
+ obj[0] = 5;
+ threw = false;
+ } catch (e) {
+ threw = true;
+ }
+ ok(threw,
+ "Should throw in strict mode when setting indexed property on " + obj);
+
+ try {
+ obj[1000] = 5;
+ threw = false;
+ } catch (e) {
+ threw = true;
+ }
+ ok(threw,
+ "Should throw in strict mode when setting out of bounds indexed property on " + obj);
+
+ try {
+ Object.defineProperty(obj, "0", { value: 17 });
+ threw = false;
+ } catch (e) {
+ threw = true;
+ }
+ ok(threw,
+ "Should throw in strict mode when defining indexed property on " + obj);
+}
+function indexedSetNonStrict(obj) {
+ var threw;
+ try {
+ obj[0] = 5;
+ threw = false;
+ } catch (e) {
+ threw = true;
+ }
+ ok(!threw,
+ "Should not throw in non-strict mode when setting indexed property on " + obj);
+
+ try {
+ obj[1000] = 5;
+ threw = false;
+ } catch (e) {
+ threw = true;
+ }
+ ok(!threw,
+ "Should not throw in non-strict mode when setting out of bounds indexed property on " + obj);
+
+ try {
+ Object.defineProperty(obj, "0", { value: 17 });
+ threw = false;
+ } catch (e) {
+ threw = true;
+ }
+ ok(threw,
+ "Should throw in non-strict mode when defining indexed property on " + obj);
+}
+for (let obj of [ document.forms, document.childNodes ]) {
+ indexedSetStrict(obj);
+ indexedSetNonStrict(obj);
+}
+</script>
+</body>
+</html>
diff --git a/dom/bindings/test/test_document_location_set_via_xray.html b/dom/bindings/test/test_document_location_set_via_xray.html
new file mode 100644
index 0000000000..2c8d01aeda
--- /dev/null
+++ b/dom/bindings/test/test_document_location_set_via_xray.html
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=905493
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 905493</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=905493">Mozilla Bug 905493</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe id="t" src="http://example.org/tests/dom/bindings/test/file_document_location_set_via_xray.html"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 905493 **/
+
+function test() {
+ var doc = document.getElementById("t").contentWindow.document;
+ ok(!("x" in doc), "Should have an Xray here");
+ is(doc.x, undefined, "Really should have an Xray here");
+ is(doc.wrappedJSObject.x, 5, "And wrapping the right thing");
+ document.getElementById("t").onload = function() {
+ ok(true, "Load happened");
+ SimpleTest.finish();
+ };
+ try {
+ // Test the forwarding location setter
+ doc.location = "chrome://mochikit/content/tests/SimpleTest/test.css";
+ } catch (e) {
+ // Load failed
+ ok(false, "Load failed");
+ SimpleTest.finish();
+ }
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(test);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_document_location_via_xray_cached.html b/dom/bindings/test/test_document_location_via_xray_cached.html
new file mode 100644
index 0000000000..f47f78cd55
--- /dev/null
+++ b/dom/bindings/test/test_document_location_via_xray_cached.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1041731
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1041731</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1041731">Mozilla Bug 1041731</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe id="t" src="http://example.org/tests/dom/bindings/test/file_document_location_set_via_xray.html"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 1041731 **/
+
+function test() {
+ var loc = document.getElementById("t").contentWindow.document.location;
+ is(loc.toString, loc.toString, "Unforgeable method on the Xray should be cached");
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(test);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_domProxyArrayLengthGetter.html b/dom/bindings/test/test_domProxyArrayLengthGetter.html
new file mode 100644
index 0000000000..e2ce1fb870
--- /dev/null
+++ b/dom/bindings/test/test_domProxyArrayLengthGetter.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1221421
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1221421</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="text/javascript">
+
+ var x = document.documentElement.style;
+ x.__proto__ = [1, 2, 3];
+
+ var res = 0;
+ for (var h = 0; h < 5000; ++h) {
+ res += x.length;
+ }
+ is(res, 15000, "length getter should return array length");
+
+ </script>
+</head>
+
+<body>
+ <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1221421">Mozilla Bug 1221421</a>
+</body>
+</html>
diff --git a/dom/bindings/test/test_dom_xrays.html b/dom/bindings/test/test_dom_xrays.html
new file mode 100644
index 0000000000..6d65ab7315
--- /dev/null
+++ b/dom/bindings/test/test_dom_xrays.html
@@ -0,0 +1,386 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=787070
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 787070</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=787070">Mozilla Bug 787070</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe id="t" src="http://example.org/tests/dom/bindings/test/file_dom_xrays.html"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 1021066 **/
+
+// values should contain the values that the property should have on each of
+// the objects on the prototype chain of obj. A value of undefined signals
+// that the value should not be present on that prototype.
+function checkXrayProperty(obj, name, values) {
+ var instance = obj;
+ do {
+ var value = values.shift();
+ if (typeof value == "undefined") {
+ ok(!obj.hasOwnProperty(name), "hasOwnProperty shouldn't see \"" + String(name) + "\" through Xrays");
+ is(Object.getOwnPropertyDescriptor(obj, name), undefined, "getOwnPropertyDescriptor shouldn't see \"" + String(name) + "\" through Xrays");
+ ok(!Object.keys(obj).includes(name), "Enumerating the Xray should not return \"" + String(name) + "\"");
+ ok(!Object.getOwnPropertyNames(obj).includes(name),
+ `The Xray's property names should not include ${String(name)}`);
+ ok(!Object.getOwnPropertySymbols(obj).includes(name),
+ `The Xray's property symbols should not include ${String(name)}`);
+ } else {
+ ok(obj.hasOwnProperty(name), "hasOwnProperty should see \"" + String(name) + "\" through Xrays");
+ var pd = Object.getOwnPropertyDescriptor(obj, name);
+ ok(pd, "getOwnPropertyDescriptor should see \"" + String(name) + "\" through Xrays");
+ if (pd && pd.get) {
+ is(pd.get.call(instance), value, "Should get the right value for \"" + String(name) + "\" through Xrays");
+ } else {
+ is(obj[name], value, "Should get the right value for \"" + String(name) + "\" through Xrays");
+ }
+ if (pd) {
+ if (pd.enumerable) {
+ ok(Object.keys(obj).indexOf("" + name) > -1, "Enumerating the Xray should return \"" + String(name) + "\"");
+ }
+ if (typeof name == "symbol") {
+ ok(Object.getOwnPropertySymbols(obj).includes(name),
+ `The Xray's property symbols should include ${String(name)}`);
+ } else {
+ ok(Object.getOwnPropertyNames(obj).includes("" + name),
+ `The Xray's property names should include ${name}`);
+ }
+ }
+ }
+ } while ((obj = Object.getPrototypeOf(obj)));
+}
+
+function checkWindowXrayProperty(win, name, { windowValue, windowPrototypeValue, namedPropertiesValue, eventTargetPrototypeValue }) {
+ checkXrayProperty(win, name, [ windowValue, windowPrototypeValue, namedPropertiesValue, eventTargetPrototypeValue ]);
+}
+function checkDocumentXrayProperty(doc, name, { documentValue, htmlDocumentPrototypeValue, documentPrototypeValue, nodePrototypeValue, eventTargetPrototypeValue }) {
+ checkXrayProperty(doc, name, [ documentValue, htmlDocumentPrototypeValue, documentPrototypeValue, nodePrototypeValue, eventTargetPrototypeValue ]);
+}
+
+function test() {
+ // Window
+ var win = document.getElementById("t").contentWindow;
+ var doc = document.getElementById("t").contentDocument;
+
+ var winProto = Object.getPrototypeOf(win);
+ is(winProto, win.Window.prototype, "The proto chain of the Xray should mirror the prototype chain of the Xrayed object");
+
+ var namedPropertiesObject = Object.getPrototypeOf(winProto);
+ is(Cu.getClassName(namedPropertiesObject, /* unwrap = */ true), "WindowProperties", "The proto chain of the Xray should mirror the prototype chain of the Xrayed object");
+
+ var eventTargetProto = Object.getPrototypeOf(namedPropertiesObject);
+ is(eventTargetProto, win.EventTarget.prototype, "The proto chain of the Xray should mirror the prototype chain of the Xrayed object");
+
+ let docProto = Object.getPrototypeOf(doc);
+ is(docProto, win.HTMLDocument.prototype, "The proto chain of the Xray should mirror the prototype chain of the Xrayed object");
+
+ // Xrays need to filter expandos.
+ checkDocumentXrayProperty(doc, "expando", {});
+ ok(!("expando" in doc), "Xrays should filter expandos");
+
+ checkDocumentXrayProperty(doc, "shadowedIframe", {});
+ ok(!("shadowedIframe" in doc), "Named properties should not be exposed through Xrays");
+
+ // Named properties live on the named properties object for global objects,
+ // but are not exposed via Xrays.
+ checkWindowXrayProperty(win, "iframe", {});
+ ok(!("iframe" in win), "Named properties should not be exposed through Xrays");
+
+ // Window properties live on the instance, shadowing the properties of the named property object.
+ checkWindowXrayProperty(win, "document", { windowValue: doc });
+ ok("document" in win, "WebIDL properties should be exposed through Xrays");
+
+ // Unforgeable properties live on the instance, shadowing the properties of the named property object.
+ checkWindowXrayProperty(win, "self", { windowValue: win });
+ ok("self" in win, "WebIDL properties should be exposed through Xrays");
+
+ // Named properties live on the instance for non-global objects, but are not
+ // exposed via Xrays.
+ checkDocumentXrayProperty(doc, "iframe", {});
+ ok(!("iframe" in doc), "Named properties should not be exposed through Xrays");
+
+ // Object.prototype is at the end of the prototype chain.
+ var obj = win;
+ var proto;
+ while ((proto = Object.getPrototypeOf(obj))) {
+ obj = proto;
+ }
+ is(obj, win.Object.prototype, "Object.prototype should be at the end of the prototype chain");
+
+ // Named properties shouldn't shadow WebIDL- or ECMAScript-defined properties.
+ checkWindowXrayProperty(win, "addEventListener", { eventTargetPrototypeValue: eventTargetProto.addEventListener });
+ is(win.addEventListener, eventTargetProto.addEventListener, "Named properties shouldn't shadow WebIDL-defined properties");
+
+ is(win.toString, win.Object.prototype.toString, "Named properties shouldn't shadow ECMAScript-defined properties");
+
+ // WebIDL interface names should be exposed.
+ var waivedWin = Cu.waiveXrays(win);
+ checkWindowXrayProperty(win, "Element", { windowValue: Cu.unwaiveXrays(waivedWin.Element) });
+
+ // JS standard classes should be exposed.
+ checkWindowXrayProperty(win, "Array", { windowValue: Cu.unwaiveXrays(waivedWin.Array) });
+
+ // HTMLDocument
+ // Unforgeable properties live on the instance.
+ checkXrayProperty(doc, "location", [ win.location ]);
+ is(String(win.location), document.getElementById("t").src,
+ "Should have the right stringification");
+
+ // HTMLHtmlElement
+ var elem = doc.documentElement;
+
+ var elemProto = Object.getPrototypeOf(elem);
+ is(elemProto, win.HTMLHtmlElement.prototype, "The proto chain of the Xray should mirror the prototype chain of the Xrayed object");
+
+ elemProto = Object.getPrototypeOf(elemProto);
+ is(elemProto, win.HTMLElement.prototype, "The proto chain of the Xray should mirror the prototype chain of the Xrayed object");
+
+ elemProto = Object.getPrototypeOf(elemProto);
+ is(elemProto, win.Element.prototype, "The proto chain of the Xray should mirror the prototype chain of the Xrayed object");
+
+ elemProto = Object.getPrototypeOf(elemProto);
+ is(elemProto, win.Node.prototype, "The proto chain of the Xray should mirror the prototype chain of the Xrayed object");
+
+ elemProto = Object.getPrototypeOf(elemProto);
+ is(elemProto, win.EventTarget.prototype, "The proto chain of the Xray should mirror the prototype chain of the Xrayed object");
+
+ // Xrays need to filter expandos.
+ ok(!("expando" in elem), "Xrays should filter expandos");
+
+ // WebIDL-defined properties live on the prototype.
+ checkXrayProperty(elem, "version", [ undefined, "" ]);
+ is(elem.version, "", "WebIDL properties should be exposed through Xrays");
+
+ // HTMLCollection
+ var coll = doc.getElementsByTagName("iframe");
+
+ // Named properties live on the instance for non-global objects.
+ checkXrayProperty(coll, "iframe", [ doc.getElementById("iframe") ]);
+
+ // Indexed properties live on the instance.
+ checkXrayProperty(coll, 0, [ doc.getElementById("shadowedIframe") ]);
+
+ // WebIDL-defined properties live on the prototype, overriding any named properties.
+ checkXrayProperty(coll, "item", [ undefined, win.HTMLCollection.prototype.item ]);
+
+ // ECMAScript-defined properties live on the prototype, overriding any named properties.
+ checkXrayProperty(coll, "toString", [ undefined, undefined, win.Object.prototype.toString ]);
+
+ // Frozen arrays should come from our compartment, not the target one.
+ var languages1 = win.navigator.languages;
+ isnot(languages1, undefined, "Must have .languages");
+ ok(Array.isArray(languages1), ".languages should be an array");
+ ok(Object.isFrozen(languages1), ".languages should be a frozen array");
+ ok(!Cu.isXrayWrapper(languages1), "Should have our own version of array");
+ is(Cu.getGlobalForObject(languages1), window,
+ "languages1 should come from our window");
+ // We want to get .languages in the content compartment, but without waiving
+ // Xrays altogether.
+ var languages2 = win.eval("navigator.languages");
+ isnot(languages2, undefined, "Must still have .languages");
+ ok(Array.isArray(languages2), ".languages should still be an array");
+ ok(Cu.isXrayWrapper(languages2), "Should have xray for content version of array");
+ is(Cu.getGlobalForObject(languages2), win,
+ "languages2 come from the underlying window");
+ ok(Object.isFrozen(languages2.wrappedJSObject),
+ ".languages should still be a frozen array underneath");
+ isnot(languages1, languages2, "Must have distinct arrays");
+ isnot(languages1, languages2.wrappedJSObject,
+ "Must have distinct arrays no matter how we slice it");
+
+ // Check that deleters work correctly in the [OverrideBuiltins] case.
+ elem = win.document.documentElement;
+ var dataset = elem.dataset;
+ is(dataset.foo, undefined, "Should not have a 'foo' property");
+ ok(!("foo" in dataset), "Really should not have a 'foo' property");
+ is(elem.getAttribute("data-foo"), null,
+ "Should not have a 'data-foo' attribute");
+ ok(!elem.hasAttribute("data-foo"),
+ "Really should not have a 'data-foo' attribute");
+ dataset.foo = "bar";
+ is(dataset.foo, "bar", "Should now have a 'foo' property");
+ ok("foo" in dataset, "Really should have a 'foo' property");
+ is(elem.getAttribute("data-foo"), "bar",
+ "Should have a 'data-foo' attribute");
+ ok(elem.hasAttribute("data-foo"),
+ "Really should have a 'data-foo' attribute");
+ delete dataset.foo;
+ is(dataset.foo, undefined, "Should not have a 'foo' property again");
+ ok(!("foo" in dataset), "Really should not have a 'foo' property again");
+ is(elem.getAttribute("data-foo"), null,
+ "Should not have a 'data-foo' attribute again");
+ ok(!elem.hasAttribute("data-foo"),
+ "Really should not have a 'data-foo' attribute again");
+
+ // Check that deleters work correctly in the non-[OverrideBuiltins] case.
+ var storage = win.sessionStorage;
+ is(storage.foo, undefined, "Should not have a 'foo' property");
+ ok(!("foo" in storage), "Really should not have a 'foo' property");
+ is(storage.getItem("foo"), null, "Should not have an item named 'foo'");
+ storage.foo = "bar";
+ is(storage.foo, "bar", "Should have a 'foo' property");
+ ok("foo" in storage, "Really should have a 'foo' property");
+ is(storage.getItem("foo"), "bar", "Should have an item named 'foo'");
+ delete storage.foo;
+ is(storage.foo, undefined, "Should not have a 'foo' property again");
+ ok(!("foo" in storage), "Really should not have a 'foo' property again");
+ is(storage.getItem("foo"), null, "Should not have an item named 'foo' again");
+
+ // Non-static properties are not exposed on interface objects or instances.
+ is(win.HTMLInputElement.checkValidity, undefined,
+ "Shouldn't see non-static property on interface objects");
+ is(Object.getOwnPropertyDescriptor(win.HTMLInputElement, "checkValidity"), undefined,
+ "Shouldn't see non-static property on interface objects");
+ is(Object.getOwnPropertyNames(win.HTMLInputElement).indexOf("checkValidity"), -1,
+ "Shouldn't see non-static property on interface objects");
+ isnot(typeof doc.createElement("input").checkValidity, "undefined",
+ "Should see non-static property on prototype objects");
+ is(Object.getOwnPropertyDescriptor(doc.createElement("input"), "checkValidity"), undefined,
+ "Shouldn't see non-static property on instances");
+ isnot(typeof Object.getOwnPropertyDescriptor(win.HTMLInputElement.prototype, "checkValidity"), "undefined",
+ "Should see non-static property on prototype objects");
+
+ // Static properties are not exposed on prototype objects or instances.
+ isnot(typeof win.URL.createObjectURL, "undefined",
+ "Should see static property on interface objects");
+ isnot(typeof Object.getOwnPropertyDescriptor(win.URL, "createObjectURL"), "undefined",
+ "Should see static property on interface objects");
+ isnot(Object.getOwnPropertyNames(win.URL).indexOf("createObjectURL"), -1,
+ "Should see static property on interface objects");
+ is(new URL("http://example.org").createObjectURL, undefined,
+ "Shouldn't see static property on instances and prototype ojbects");
+ is(Object.getOwnPropertyDescriptor(new URL("http://example.org"), "createObjectURL"), undefined,
+ "Shouldn't see static property on instances");
+ is(Object.getOwnPropertyDescriptor(win.URL.prototype, "createObjectURL"), undefined,
+ "Shouldn't see static property on prototype objects");
+
+ // Unforgeable properties are not exposed on prototype objects or interface
+ // objects.
+ is(Window.document, undefined,
+ "Shouldn't see unforgeable property on interface objects");
+ is(Object.getOwnPropertyDescriptor(Window, "document"), undefined,
+ "Shouldn't see unforgeable property on interface objects");
+ is(Object.getOwnPropertyNames(Window).indexOf("document"), -1,
+ "Shouldn't see unforgeable property on interface objects");
+ isnot(typeof win.document, "undefined",
+ "Should see unforgeable property on instances");
+ isnot(typeof Object.getOwnPropertyDescriptor(win, "document"), "undefined",
+ "Should see unforgeable property on instances");
+ is(Object.getOwnPropertyDescriptor(Window.prototype, "document"), undefined,
+ "Shouldn't see unforgeable property on prototype objects");
+
+ // Constant properties are not exposted on instances.
+ isnot(typeof win.Node.ELEMENT_NODE, "undefined",
+ "Should see constant property on interface objects");
+ isnot(typeof Object.getOwnPropertyDescriptor(win.Node, "ELEMENT_NODE"), "undefined",
+ "Should see constant property on interface objects");
+ isnot(Object.getOwnPropertyNames(win.Node).indexOf("ELEMENT_NODE"), -1,
+ "Should see constant property on interface objects");
+ isnot(typeof elem.ELEMENT_NODE, "undefined",
+ "Should see constant property on prototype objects");
+ is(Object.getOwnPropertyDescriptor(elem, "ELEMENT_NODE"), undefined,
+ "Shouldn't see constant property on instances");
+ isnot(typeof Object.getOwnPropertyDescriptor(win.Node.prototype, "ELEMENT_NODE"), "undefined",
+ "Should see constant property on prototype objects");
+
+ // Interfaces can have both static and non-static properties with the same name.
+ isnot(typeof win.TestFunctions.staticAndNonStaticOverload, "undefined",
+ "Should see static property on interface objects (even with non-static property with the same name)");
+ isnot(typeof Object.getOwnPropertyDescriptor(win.TestFunctions, "staticAndNonStaticOverload"), "undefined",
+ "Should see static property on interface objects (even with non-static property with the same name)");
+ isnot(Object.getOwnPropertyNames(win.TestFunctions).indexOf("staticAndNonStaticOverload"), -1,
+ "Should see static property on interface objects (even with non-static property with the same name)");
+ isnot(typeof (new win.TestFunctions("")).staticAndNonStaticOverload, "undefined",
+ "Should see non-static property on prototype objects (even with static property with the same name)");
+ let testFunctions = new win.TestFunctions();
+ is(Object.getOwnPropertyDescriptor(testFunctions, "staticAndNonStaticOverload"), undefined,
+ "Shouldn't see non-static property on instances (even with static property with the same name)");
+ ok(!testFunctions.staticAndNonStaticOverload(),
+ "Should call the non-static overload on the instance");
+ ok(win.TestFunctions.staticAndNonStaticOverload(),
+ "Should call the static overload on the interface object");
+ isnot(typeof Object.getOwnPropertyDescriptor(win.TestFunctions.prototype, "staticAndNonStaticOverload"), "undefined",
+ "Should see non-static property on prototype objects (even with static property with the same name)");
+ is(Object.getOwnPropertyDescriptor(win.TestFunctions, "staticAndNonStaticOverload").value,
+ Object.getOwnPropertyDescriptor(win.TestFunctions, "staticAndNonStaticOverload").value,
+ "Should get the same value when getting the static property twice");
+ is(Object.getOwnPropertyDescriptor(win.TestFunctions.prototype, "staticAndNonStaticOverload").value,
+ Object.getOwnPropertyDescriptor(win.TestFunctions.prototype, "staticAndNonStaticOverload").value,
+ "Should get the same value when getting the non-static property twice");
+ isnot(Object.getOwnPropertyDescriptor(win.TestFunctions, "staticAndNonStaticOverload").value,
+ Object.getOwnPropertyDescriptor(win.TestFunctions.prototype, "staticAndNonStaticOverload").value,
+ "Should get different values for static and non-static properties with the same name");
+
+ // Adopting nodes should not lose expandos.
+ elem = document.createElement("span");
+ elem.expando = 5;
+ is(elem.expando, 5, "We just set this property");
+ document.adoptNode(elem);
+ is(elem.wrappedJSObject, undefined, "Shouldn't be an Xray anymore");
+ is(elem.expando, 5, "Expando should not get lost");
+
+ // Instanceof tests
+ var img = doc.createElement("img");
+ var img2 = document.createElement("img");
+ ok(img instanceof win.HTMLImageElement,
+ "Should be an instance of HTMLImageElement from its global");
+ ok(win.HTMLImageElement.isInstance(img), "isInstance should work");
+ ok(HTMLImageElement.isInstance(img), "isInstance should work cross-global");
+ ok(win.HTMLImageElement.isInstance(img2),
+ "isInstance should work cross-global in the other direction");
+ ok(img instanceof win.Image,
+ "Should be an instance of Image, because Image.prototype == HTMLImageElement.prototype");
+ ok(!win.Image.isInstance, "Shouldn't have an isInstance method here");
+ // Image does not have a Symbol.hasInstance, but its proto
+ // (Function.prototype) does.
+ checkXrayProperty(win.Image, Symbol.hasInstance,
+ [undefined, win.Function.prototype[Symbol.hasInstance]]);
+
+ // toString/@@toStringTag
+ let imageConstructor = win.Image;
+ is(win.Function.prototype.toString.apply(imageConstructor),
+ Function.prototype.toString.apply(Image),
+ "Applying Function.prototype.toString through an Xray should give the same result as applying it directly");
+ isDeeply(Object.getOwnPropertyDescriptor(win.CSS, Symbol.toStringTag),
+ Object.getOwnPropertyDescriptor(CSS, Symbol.toStringTag),
+ "Getting @@toStringTag on a namespace object through an Xray should give the same result as getting it directly");
+
+ // legacyCaller should work.
+ ok(win.HTMLAllCollection.isInstance(doc.all),
+ "HTMLDocument.all should be an instance of HTMLAllCollection");
+ let element, threw;
+ try {
+ threw = false;
+ element = doc.all(0);
+ } catch (e) {
+ threw = true;
+ }
+ ok(!threw,
+ "Calling an instance object for an interface marked with legacycaller shouldn't throw");
+ checkXrayProperty(doc.all, 0, [ element ]);
+
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestLongerTimeout(2);
+
+addLoadEvent(() => {
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]},
+ test);
+});
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_enums.html b/dom/bindings/test/test_enums.html
new file mode 100644
index 0000000000..95f23885bb
--- /dev/null
+++ b/dom/bindings/test/test_enums.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Enums</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+/* global test, assert_equals */
+test(function() {
+ var xhr = new XMLHttpRequest();
+ xhr.open("get", "foo");
+ assert_equals(xhr.responseType, "");
+ xhr.responseType = "foo";
+ assert_equals(xhr.responseType, "");
+}, "Assigning an invalid value to an enum attribute should not throw.");
+</script>
diff --git a/dom/bindings/test/test_exceptionSanitization.html b/dom/bindings/test/test_exceptionSanitization.html
new file mode 100644
index 0000000000..818d750136
--- /dev/null
+++ b/dom/bindings/test/test_exceptionSanitization.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1295322
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1295322</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=1295322">Mozilla Bug 1295322</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+ <script type="application/javascript">
+ /* global TestFunctions */
+ SimpleTest.waitForExplicitFinish();
+ async function runTests() {
+ await SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]});
+
+ var t = new TestFunctions();
+
+ try {
+ t.testThrowNsresult();
+ } catch (e) {
+ try {
+ is(e.name, "NS_BINDING_ABORTED", "Should have the right exception");
+ is(e.filename, location.href, "Should not be seeing where the exception really came from");
+ } catch (e2) {
+ ok(false, "Should be able to work with the exception");
+ }
+ }
+
+ try {
+ t.testThrowNsresultFromNative();
+ } catch (e) {
+ try {
+ is(e.name, "NS_ERROR_UNEXPECTED", "Should have the right exception");
+ is(e.filename, location.href, "Should not be seeing where the exception really came from");
+ } catch (e2) {
+ ok(false, "Should be able to work with the exception");
+ }
+ }
+
+ SimpleTest.finish();
+ }
+
+ runTests();
+ </script>
+</body>
+</html>
diff --git a/dom/bindings/test/test_exceptionThrowing.html b/dom/bindings/test/test_exceptionThrowing.html
new file mode 100644
index 0000000000..571d21b485
--- /dev/null
+++ b/dom/bindings/test/test_exceptionThrowing.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=847119
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 847119</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 847119 **/
+
+ var xhr = new XMLHttpRequest();
+ var domthrows = function() { xhr.open(); };
+
+ var count = 20000;
+
+ function f() {
+ var k = 0;
+ for (var j = 0; j < count; ++j) {
+ try { domthrows(); } catch (e) { ++k; }
+ }
+ return k;
+ }
+ function g() { return count; }
+
+ is(f(), count, "Should get count exceptions");
+ for (let h of [f, g]) {
+ try { is(h(), count, "Should get count exceptions here too"); } catch (e) {}
+ }
+ ok(true, "We should get here");
+
+ domthrows = function() { xhr.withCredentials = false; };
+ xhr.open("GET", "");
+ xhr.send();
+
+ is(f(), count, "Should get count exceptions from getter");
+ for (let h of [f, g]) {
+ try { is(h(), count, "Should get count exceptions from getter here too"); } catch (e) {}
+ }
+ ok(true, "We should get here too");
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=847119">Mozilla Bug 847119</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_exception_messages.html b/dom/bindings/test/test_exception_messages.html
new file mode 100644
index 0000000000..ffa1937e7e
--- /dev/null
+++ b/dom/bindings/test/test_exception_messages.html
@@ -0,0 +1,83 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=882653
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 882653</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 882653 **/
+ // Each test is a string to eval, the expected exception message, and the
+ // test description.
+ var tests = [
+ [ "document.documentElement.appendChild.call({}, new Image())",
+ "'appendChild' called on an object that does not implement interface Node.",
+ "bogus method this object" ],
+ [ 'Object.getOwnPropertyDescriptor(Document.prototype, "documentElement").get.call({})',
+ "'get documentElement' called on an object that does not implement interface Document.",
+ "bogus getter this object" ],
+ [ 'Object.getOwnPropertyDescriptor(Element.prototype, "innerHTML").set.call({})',
+ "'set innerHTML' called on an object that does not implement interface Element.",
+ "bogus setter this object" ],
+ [ "document.documentElement.appendChild(5)",
+ "Node.appendChild: Argument 1 is not an object.",
+ "bogus interface argument" ],
+ [ "document.documentElement.appendChild(null)",
+ "Node.appendChild: Argument 1 is not an object.",
+ "null interface argument" ],
+ [ "document.createTreeWalker(document).currentNode = 5",
+ "TreeWalker.currentNode setter: Value being assigned is not an object.",
+ "interface setter call" ],
+ [ "document.documentElement.appendChild({})",
+ "Node.appendChild: Argument 1 does not implement interface Node.",
+ "wrong interface argument" ],
+ [ "document.createTreeWalker(document).currentNode = {}",
+ "TreeWalker.currentNode setter: Value being assigned does not implement interface Node.",
+ "wrong interface setter call" ],
+ [ 'document.createElement("canvas").getContext("2d").fill("bogus")',
+ "CanvasRenderingContext2D.fill: 'bogus' (value of argument 1) is not a valid value for enumeration CanvasWindingRule.",
+ "bogus enum value" ],
+ [ "document.createTreeWalker(document, 0xFFFFFFFF, { acceptNode: 5 }).nextNode()",
+ "Property 'acceptNode' is not callable.",
+ "non-callable callback interface operation property" ],
+ [ "(new TextDecoder).decode(new Uint8Array(), 5)",
+ "TextDecoder.decode: Argument 2 can't be converted to a dictionary.",
+ "primitive passed for a dictionary" ],
+ [ "URL.createObjectURL(null)",
+ "URL.createObjectURL: Argument 1 is not valid for any of the 1-argument overloads.",
+ "overload resolution failure" ],
+ [ 'document.createElement("select").add({})',
+ "HTMLSelectElement.add: Argument 1 could not be converted to any of: HTMLOptionElement, HTMLOptGroupElement.",
+ "invalid value passed for union" ],
+ [ 'document.createElement("canvas").getContext("2d").createLinearGradient(0, 1, 0, 1).addColorStop(NaN, "")',
+ "CanvasGradient.addColorStop: Argument 1 is not a finite floating-point value.",
+ "invalid float" ],
+ ];
+
+ for (var i = 0; i < tests.length; ++i) {
+ var msg = "Correct exception should be thrown for " + tests[i][2];
+ try {
+ // eslint-disable-next-line no-eval
+ eval(tests[i][0]);
+ ok(false, msg);
+ } catch (e) {
+ is(e.message, tests[i][1], msg);
+ }
+ }
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=882653">Mozilla Bug 882653</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_exception_options_from_jsimplemented.html b/dom/bindings/test/test_exception_options_from_jsimplemented.html
new file mode 100644
index 0000000000..d7d243b0d0
--- /dev/null
+++ b/dom/bindings/test/test_exception_options_from_jsimplemented.html
@@ -0,0 +1,166 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1107592
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1107592</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+ /* global TestInterfaceJS */
+ /** Test for Bug 1107592 **/
+
+ SimpleTest.waitForExplicitFinish();
+
+ function doTest() {
+ var file = location.href;
+
+ var asyncFrame;
+ /* Async parent frames from pushPrefEnv don't show up in e10s. */
+ if (!SpecialPowers.getBoolPref("javascript.options.asyncstack_capture_debuggee_only")) {
+ asyncFrame = `Async*@${file}:153:17
+`;
+ } else {
+ asyncFrame = "";
+ }
+
+ var t = new TestInterfaceJS();
+ try {
+ t.testThrowError();
+ } catch (e) {
+ ok(e instanceof Error, "Should have an Error here");
+ ok(!(e instanceof DOMException), "Should not have DOMException here");
+ ok(!("code" in e), "Should not have a 'code' property");
+ is(e.name, "Error", "Should not have an interesting name here");
+ is(e.message, "We are an Error", "Should have the right message");
+ is(e.stack,
+ `doTest@${file}:31:9
+${asyncFrame}`,
+ "Exception stack should still only show our code");
+ is(e.fileName,
+ file,
+ "Should have the right file name");
+ is(e.lineNumber, 31, "Should have the right line number");
+ is(e.columnNumber, 9, "Should have the right column number");
+ }
+
+ try {
+ t.testThrowDOMException();
+ } catch (e) {
+ ok(e instanceof Error, "Should also have an Error here");
+ ok(e instanceof DOMException, "Should have DOMException here");
+ is(e.name, "NotSupportedError", "Should have the right name here");
+ is(e.message, "We are a DOMException",
+ "Should also have the right message");
+ is(e.code, DOMException.NOT_SUPPORTED_ERR,
+ "Should have the right 'code'");
+ is(e.stack,
+ `doTest@${file}:50:9
+${asyncFrame}`,
+ "Exception stack should still only show our code");
+ is(e.filename,
+ file,
+ "Should still have the right file name");
+ is(e.lineNumber, 50, "Should still have the right line number");
+ todo_isnot(e.columnNumber, 0,
+ "No column number support for DOMException yet");
+ }
+
+ try {
+ t.testThrowTypeError();
+ } catch (e) {
+ ok(e instanceof TypeError, "Should have a TypeError here");
+ ok(!(e instanceof DOMException), "Should not have DOMException here (2)");
+ ok(!("code" in e), "Should not have a 'code' property (2)");
+ is(e.name, "TypeError", "Should be named TypeError");
+ is(e.message, "We are a TypeError",
+ "Should also have the right message (2)");
+ is(e.stack,
+ `doTest@${file}:72:9
+${asyncFrame}`,
+ "Exception stack for TypeError should only show our code");
+ is(e.fileName,
+ file,
+ "Should still have the right file name for TypeError");
+ is(e.lineNumber, 72, "Should still have the right line number for TypeError");
+ is(e.columnNumber, 9, "Should have the right column number for TypeError");
+ }
+
+ try {
+ t.testThrowCallbackError(function() { Array.prototype.forEach(); });
+ } catch (e) {
+ ok(e instanceof TypeError, "Should have a TypeError here (3)");
+ ok(!(e instanceof DOMException), "Should not have DOMException here (3)");
+ ok(!("code" in e), "Should not have a 'code' property (3)");
+ is(e.name, "TypeError", "Should be named TypeError (3)");
+ is(e.message, "missing argument 0 when calling function Array.prototype.forEach",
+ "Should also have the right message (3)");
+ is(e.stack,
+ `doTest/<@${file}:92:61
+doTest@${file}:92:9
+${asyncFrame}`,
+ "Exception stack for TypeError should only show our code (3)");
+ is(e.fileName,
+ file,
+ "Should still have the right file name for TypeError (3)");
+ is(e.lineNumber, 92, "Should still have the right line number for TypeError (3)");
+ is(e.columnNumber, 61, "Should have the right column number for TypeError (3)");
+ }
+
+ try {
+ t.testThrowXraySelfHosted();
+ } catch (e) {
+ ok(!(e instanceof Error), "Should have an Exception here (4)");
+ ok(!(e instanceof DOMException), "Should not have DOMException here (4)");
+ ok(!("code" in e), "Should not have a 'code' property (4)");
+ is(e.name, "NS_ERROR_UNEXPECTED", "Name should be sanitized (4)");
+ is(e.message, "", "Message should be sanitized (5)");
+ is(e.stack,
+ `doTest@${file}:113:9
+${asyncFrame}`,
+ "Exception stack for sanitized exception should only show our code (4)");
+ is(e.filename,
+ file,
+ "Should still have the right file name for sanitized exception (4)");
+ is(e.lineNumber, 113, "Should still have the right line number for sanitized exception (4)");
+ todo_isnot(e.columnNumber, 0, "Should have the right column number for sanitized exception (4)");
+ }
+
+ try {
+ t.testThrowSelfHosted();
+ } catch (e) {
+ ok(!(e instanceof Error), "Should have an Exception here (5)");
+ ok(!(e instanceof DOMException), "Should not have DOMException here (5)");
+ ok(!("code" in e), "Should not have a 'code' property (5)");
+ is(e.name, "NS_ERROR_UNEXPECTED", "Name should be sanitized (5)");
+ is(e.message, "", "Message should be sanitized (5)");
+ is(e.stack,
+ `doTest@${file}:132:9
+${asyncFrame}`,
+ "Exception stack for sanitized exception should only show our code (5)");
+ is(e.filename,
+ file,
+ "Should still have the right file name for sanitized exception (5)");
+ is(e.lineNumber, 132, "Should still have the right line number for sanitized exception (5)");
+ todo_isnot(e.columnNumber, 0, "Should have the right column number for sanitized exception (5)");
+ }
+
+ SimpleTest.finish();
+ }
+
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]},
+ doTest);
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1107592">Mozilla Bug 1107592</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_exceptions_from_jsimplemented.html b/dom/bindings/test/test_exceptions_from_jsimplemented.html
new file mode 100644
index 0000000000..89faf0c46f
--- /dev/null
+++ b/dom/bindings/test/test_exceptions_from_jsimplemented.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=923010
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 923010</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+ /** Test for Bug 923010 **/
+ try {
+ var conn = new RTCPeerConnection();
+
+ var candidate = new RTCIceCandidate({candidate: "x" });
+ conn.addIceCandidate(candidate)
+ .then(function() {
+ ok(false, "addIceCandidate succeeded when it should have failed");
+ }, function(reason) {
+ is(reason.lineNumber, 17, "Rejection should have been on line 17");
+ is(reason.message,
+ "Invalid candidate (both sdpMid and sdpMLineIndex are null).",
+ "Should have the rejection we expect");
+ })
+ .catch(function(reason) {
+ ok(false, "unexpected error: " + reason);
+ });
+ } catch (e) {
+ // b2g has no WebRTC, apparently
+ todo(false, "No WebRTC on b2g yet");
+ }
+
+ conn.close();
+ try {
+ conn.setIdentityProvider("example.com", { protocol: "foo" });
+ ok(false, "That call to setIdentityProvider should have thrown");
+ } catch (e) {
+ is(e.lineNumber, 36, "Exception should have been on line 36");
+ is(e.message,
+ "Peer connection is closed",
+ "Should have the exception we expect");
+ }
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=923010">Mozilla Bug 923010</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_forOf.html b/dom/bindings/test/test_forOf.html
new file mode 100644
index 0000000000..1be2506a21
--- /dev/null
+++ b/dom/bindings/test/test_forOf.html
@@ -0,0 +1,87 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=725907
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 725907</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=725907">Mozilla Bug 725907</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<div id="basket">
+ <span id="egg0"></span>
+ <span id="egg1"><span id="duckling1"></span></span>
+ <span id="egg2"></span>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 725907 **/
+
+
+function runTestsForDocument(document, msgSuffix) {
+ function is(a, b, msg) { SimpleTest.is(a, b, msg + msgSuffix); }
+
+ var basket = document.getElementById("basket");
+ var egg3 = document.createElement("span");
+ egg3.id = "egg3";
+
+ var log = "";
+ for (let x of basket.childNodes) {
+ if (x.nodeType != x.TEXT_NODE)
+ log += x.id + ";";
+ }
+ is(log, "egg0;egg1;egg2;", "'for (x of div.childNodes)' should iterate over child nodes");
+
+ log = "";
+ for (let x of basket.childNodes) {
+ if (x.nodeType != x.TEXT_NODE) {
+ log += x.id + ";";
+ if (x.id == "egg1")
+ basket.appendChild(egg3);
+ }
+ }
+ is(log, "egg0;egg1;egg2;egg3;", "'for (x of div.childNodes)' should see elements added during iteration");
+
+ log = "";
+ basket.appendChild(document.createTextNode("some text"));
+ for (let x of basket.children)
+ log += x.id + ";";
+ is(log, "egg0;egg1;egg2;egg3;", "'for (x of div.children)' should iterate over child elements");
+
+ var count = 0;
+ // eslint-disable-next-line no-unused-vars
+ for (let x of document.getElementsByClassName("hazardous-materials"))
+ count++;
+ is(count, 0, "'for (x of emptyNodeList)' loop should run zero times");
+
+ log = "";
+ for (let x of document.querySelectorAll("span"))
+ log += x.id + ";";
+ is(log, "egg0;egg1;duckling1;egg2;egg3;", "for-of loop should work with a querySelectorAll() NodeList");
+}
+
+/* All the tests run twice. First, in this document, so without any wrappers. */
+runTestsForDocument(document, "");
+
+/* And once using the document of an iframe, so working with cross-compartment wrappers. */
+SimpleTest.waitForExplicitFinish();
+function iframeLoaded(iframe) {
+ runTestsForDocument(iframe.contentWindow.document, " (in iframe)");
+ SimpleTest.finish();
+}
+
+</script>
+
+<iframe src="forOf_iframe.html" onload="iframeLoaded(this)"></iframe>
+
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_integers.html b/dom/bindings/test/test_integers.html
new file mode 100644
index 0000000000..765ed1993d
--- /dev/null
+++ b/dom/bindings/test/test_integers.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <canvas id="c" width="1" height="1"></canvas>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+ function testInt64NonFinite(arg) {
+ // We can use a WebGLRenderingContext to test conversion to 64-bit signed
+ // ints edge cases.
+ var gl = $("c").getContext("experimental-webgl");
+ if (!gl) {
+ // No WebGL support on MacOS 10.5. Just skip this test
+ todo(false, "WebGL not supported");
+ return;
+ }
+ var error = gl.getError();
+
+ // on the b2g emulator we get GL_INVALID_FRAMEBUFFER_OPERATION
+ if (error == 0x0506) // GL_INVALID_FRAMEBUFFER_OPERATION
+ return;
+
+ is(error, 0, "Should not start in an error state");
+
+ var b = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, b);
+
+ var a = new Float32Array(1);
+ gl.bufferData(gl.ARRAY_BUFFER, a, gl.STATIC_DRAW);
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, arg, a);
+
+ is(gl.getError(), 0, "Should have treated non-finite double as 0");
+ }
+
+ testInt64NonFinite(NaN);
+ testInt64NonFinite(Infinity);
+ testInt64NonFinite(-Infinity);
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_interfaceLength.html b/dom/bindings/test/test_interfaceLength.html
new file mode 100644
index 0000000000..30fde932ce
--- /dev/null
+++ b/dom/bindings/test/test_interfaceLength.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1776790
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1776790</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=1776790">Mozilla Bug 1776790</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+/* global TestInterfaceLength */
+
+add_task(async function init() {
+ await SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]});
+});
+
+/** Test for Bug 1776790 **/
+add_task(function test_interface_length() {
+ is(TestInterfaceLength.length, 0, "TestInterfaceLength.length");
+});
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_interfaceLength_chrome.html b/dom/bindings/test/test_interfaceLength_chrome.html
new file mode 100644
index 0000000000..86ec985057
--- /dev/null
+++ b/dom/bindings/test/test_interfaceLength_chrome.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1776790
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1776790</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1776790">Mozilla Bug 1776790</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+/* global TestInterfaceLength */
+
+add_task(async function init() {
+ await SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]});
+});
+
+/** Test for Bug 1776790 **/
+add_task(function test_interface_length() {
+ is(TestInterfaceLength.length, 1, "TestInterfaceLength.length");
+});
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_interfaceName.html b/dom/bindings/test/test_interfaceName.html
new file mode 100644
index 0000000000..bd06fc0cef
--- /dev/null
+++ b/dom/bindings/test/test_interfaceName.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1084001
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1084001</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1084001 **/
+ is(Image.name, "Image", "Image name");
+ is(Promise.name, "Promise", "Promise name");
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1084001">Mozilla Bug 1084001</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_interfaceToString.html b/dom/bindings/test/test_interfaceToString.html
new file mode 100644
index 0000000000..0a7ae9337f
--- /dev/null
+++ b/dom/bindings/test/test_interfaceToString.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=742156
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 742156</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=742156">Mozilla Bug 742156</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 742156 **/
+
+var nativeToString = ("" + String).replace("String", "EventTarget");
+try {
+ var eventTargetToString = "" + EventTarget;
+ is(eventTargetToString, nativeToString,
+ "Stringifying a DOM interface object should return the same string" +
+ "as stringifying a native function.");
+} catch (e) {
+ ok(false, "Stringifying a DOM interface object shouldn't throw.");
+}
+
+try {
+ eventTargetToString = Function.prototype.toString.call(EventTarget);
+ is(eventTargetToString, nativeToString,
+ "Stringifying a DOM interface object via Function.prototype.toString " +
+ "should return the same string as stringifying a native function.");
+} catch (e) {
+ ok(false, "Stringifying a DOM interface object shouldn't throw.");
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_iterable.html b/dom/bindings/test/test_iterable.html
new file mode 100644
index 0000000000..4c2dc0fc4e
--- /dev/null
+++ b/dom/bindings/test/test_iterable.html
@@ -0,0 +1,241 @@
+<!-- Any copyright is dedicated to the Public Domain.
+- http://creativecommons.org/publicdomain/zero/1.0/ -->
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Test Iterable Interface</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+ </head>
+ <body>
+ <script class="testbody" type="application/javascript">
+ /* global TestInterfaceIterableSingle, TestInterfaceIterableDouble, TestInterfaceIterableDoubleUnion */
+
+ SimpleTest.waitForExplicitFinish();
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]}, function() {
+ var base_properties = [["entries", "function", 0],
+ ["keys", "function", 0],
+ ["values", "function", 0],
+ ["forEach", "function", 1]];
+ var testExistence = function testExistence(prefix, obj, properties) {
+ for (var [name, type, args] of properties) {
+ // Properties are somewhere up the proto chain, hasOwnProperty won't work
+ isnot(obj[name], undefined,
+ `${prefix} object has property ${name}`);
+
+ is(typeof obj[name], type,
+ `${prefix} object property ${name} is a ${type}`);
+ // Check function length
+ if (type == "function") {
+ is(obj[name].length, args,
+ `${prefix} object property ${name} is length ${args}`);
+ is(obj[name].name, name,
+ `${prefix} object method name is ${name}`);
+ }
+
+ // Find where property is on proto chain, check for enumerablility there.
+ var owner = obj;
+ while (owner) {
+ var propDesc = Object.getOwnPropertyDescriptor(owner, name);
+ if (propDesc) {
+ ok(propDesc.enumerable,
+ `${prefix} object property ${name} is enumerable`);
+ break;
+ }
+ owner = Object.getPrototypeOf(owner);
+ }
+ }
+ };
+
+ var itr;
+ info("IterableSingle: Testing simple iterable creation and functionality");
+ itr = new TestInterfaceIterableSingle();
+ testExistence("IterableSingle: ", itr, base_properties);
+ is(itr[Symbol.iterator], Array.prototype[Symbol.iterator],
+ "IterableSingle: Should be using %ArrayIterator% for @@iterator");
+ is(itr.keys, Array.prototype.keys,
+ "IterableSingle: Should be using %ArrayIterator% for 'keys'");
+ is(itr.entries, Array.prototype.entries,
+ "IterableSingle: Should be using %ArrayIterator% for 'entries'");
+ is(itr.values, itr[Symbol.iterator],
+ "IterableSingle: Should be using @@iterator for 'values'");
+ is(itr.forEach, Array.prototype.forEach,
+ "IterableSingle: Should be using %ArrayIterator% for 'forEach'");
+ var keys = [...itr.keys()];
+ var values = [...itr.values()];
+ var entries = [...itr.entries()];
+ var key_itr = itr.keys();
+ var value_itr = itr.values();
+ var entries_itr = itr.entries();
+ for (let i = 0; i < 3; ++i) {
+ let key = key_itr.next();
+ let value = value_itr.next();
+ let entry = entries_itr.next();
+ is(key.value, i, "IterableSingle: Key iterator value should be " + i);
+ is(key.value, keys[i],
+ "IterableSingle: Key iterator value should match destructuring " + i);
+ is(value.value, key.value, "IterableSingle: Value iterator value should be " + key.value);
+ is(value.value, values[i],
+ "IterableSingle: Value iterator value should match destructuring " + i);
+ is(entry.value[0], i, "IterableSingle: Entry iterator value 0 should be " + i);
+ is(entry.value[1], i, "IterableSingle: Entry iterator value 1 should be " + i);
+ is(entry.value[0], entries[i][0],
+ "IterableSingle: Entry iterator value 0 should match destructuring " + i);
+ is(entry.value[1], entries[i][1],
+ "IterableSingle: Entry iterator value 1 should match destructuring " + i);
+ }
+
+ var callsToForEachCallback = 0;
+ var thisArg = {};
+ itr.forEach(function(value1, index, obj) {
+ is(index, callsToForEachCallback,
+ `IterableSingle: Should have the right index at ${callsToForEachCallback} calls to forEach callback`);
+ is(value1, values[index],
+ `IterableSingle: Should have the right value at ${callsToForEachCallback} calls to forEach callback`);
+ is(this, thisArg,
+ "IterableSingle: Should have the right this value for forEach callback");
+ is(obj, itr,
+ "IterableSingle: Should have the right third arg for forEach callback");
+ ++callsToForEachCallback;
+ }, thisArg);
+ is(callsToForEachCallback, 3,
+ "IterableSingle: Should have right total number of calls to forEach callback");
+
+ let key = key_itr.next();
+ let value = value_itr.next();
+ let entry = entries_itr.next();
+ is(key.value, undefined, "IterableSingle: Key iterator value should be undefined");
+ is(key.done, true, "IterableSingle: Key iterator done should be true");
+ is(value.value, undefined, "IterableSingle: Value iterator value should be undefined");
+ is(value.done, true, "IterableSingle: Value iterator done should be true");
+ is(entry.value, undefined, "IterableDouble: Entry iterator value should be undefined");
+ is(entry.done, true, "IterableSingle: Entry iterator done should be true");
+ is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)),
+ "[object Array Iterator]",
+ "iterator prototype should have the right brand");
+
+ // Simple dual type iterable creation and functionality test
+ info("IterableDouble: Testing simple iterable creation and functionality");
+ itr = new TestInterfaceIterableDouble();
+ testExistence("IterableDouble: ", itr, base_properties);
+ is(itr.entries, itr[Symbol.iterator],
+ "IterableDouble: Should be using @@iterator for 'entries'");
+ var elements = [["a", "b"], ["c", "d"], ["e", "f"]];
+ keys = [...itr.keys()];
+ values = [...itr.values()];
+ entries = [...itr.entries()];
+ key_itr = itr.keys();
+ value_itr = itr.values();
+ entries_itr = itr.entries();
+ for (let i = 0; i < 3; ++i) {
+ key = key_itr.next();
+ value = value_itr.next();
+ entry = entries_itr.next();
+ is(key.value, elements[i][0], "IterableDouble: Key iterator value should be " + elements[i][0]);
+ is(key.value, keys[i],
+ "IterableDouble: Key iterator value should match destructuring " + i);
+ is(value.value, elements[i][1], "IterableDouble: Value iterator value should be " + elements[i][1]);
+ is(value.value, values[i],
+ "IterableDouble: Value iterator value should match destructuring " + i);
+ is(entry.value[0], elements[i][0], "IterableDouble: Entry iterator value 0 should be " + elements[i][0]);
+ is(entry.value[1], elements[i][1], "IterableDouble: Entry iterator value 1 should be " + elements[i][1]);
+ is(entry.value[0], entries[i][0],
+ "IterableDouble: Entry iterator value 0 should match destructuring " + i);
+ is(entry.value[1], entries[i][1],
+ "IterableDouble: Entry iterator value 1 should match destructuring " + i);
+ }
+
+ callsToForEachCallback = 0;
+ thisArg = {};
+ itr.forEach(function(value1, key1, obj) {
+ is(key1, keys[callsToForEachCallback],
+ `IterableDouble: Should have the right key at ${callsToForEachCallback} calls to forEach callback`);
+ is(value1, values[callsToForEachCallback],
+ `IterableDouble: Should have the right value at ${callsToForEachCallback} calls to forEach callback`);
+ is(this, thisArg,
+ "IterableDouble: Should have the right this value for forEach callback");
+ is(obj, itr,
+ "IterableSingle: Should have the right third arg for forEach callback");
+ ++callsToForEachCallback;
+ }, thisArg);
+ is(callsToForEachCallback, 3,
+ "IterableDouble: Should have right total number of calls to forEach callback");
+
+ key = key_itr.next();
+ value = value_itr.next();
+ entry = entries_itr.next();
+ is(key.value, undefined, "IterableDouble: Key iterator value should be undefined");
+ is(key.done, true, "IterableDouble: Key iterator done should be true");
+ is(value.value, undefined, "IterableDouble: Value iterator value should be undefined");
+ is(value.done, true, "IterableDouble: Value iterator done should be true");
+ is(entry.value, undefined, "IterableDouble: Entry iterator value should be undefined");
+ is(entry.done, true, "IterableDouble: Entry iterator done should be true");
+ is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)),
+ "[object TestInterfaceIterableDouble Iterator]",
+ "iterator prototype should have the right brand");
+
+ // Simple dual type iterable creation and functionality test
+ info("IterableDoubleUnion: Testing simple iterable creation and functionality");
+ itr = new TestInterfaceIterableDoubleUnion();
+ testExistence("IterableDoubleUnion: ", itr, base_properties);
+ is(itr.entries, itr[Symbol.iterator],
+ "IterableDoubleUnion: Should be using @@iterator for 'entries'");
+ elements = [["long", 1], ["string", "a"]];
+ keys = [...itr.keys()];
+ values = [...itr.values()];
+ entries = [...itr.entries()];
+ key_itr = itr.keys();
+ value_itr = itr.values();
+ entries_itr = itr.entries();
+ for (let i = 0; i < elements.length; ++i) {
+ key = key_itr.next();
+ value = value_itr.next();
+ entry = entries_itr.next();
+ is(key.value, elements[i][0], "IterableDoubleUnion: Key iterator value should be " + elements[i][0]);
+ is(key.value, keys[i],
+ "IterableDoubleUnion: Key iterator value should match destructuring " + i);
+ is(value.value, elements[i][1], "IterableDoubleUnion: Value iterator value should be " + elements[i][1]);
+ is(value.value, values[i],
+ "IterableDoubleUnion: Value iterator value should match destructuring " + i);
+ is(entry.value[0], elements[i][0], "IterableDoubleUnion: Entry iterator value 0 should be " + elements[i][0]);
+ is(entry.value[1], elements[i][1], "IterableDoubleUnion: Entry iterator value 1 should be " + elements[i][1]);
+ is(entry.value[0], entries[i][0],
+ "IterableDoubleUnion: Entry iterator value 0 should match destructuring " + i);
+ is(entry.value[1], entries[i][1],
+ "IterableDoubleUnion: Entry iterator value 1 should match destructuring " + i);
+ }
+
+ callsToForEachCallback = 0;
+ thisArg = {};
+ itr.forEach(function(value1, key1, obj) {
+ is(key1, keys[callsToForEachCallback],
+ `IterableDoubleUnion: Should have the right key at ${callsToForEachCallback} calls to forEach callback`);
+ is(value1, values[callsToForEachCallback],
+ `IterableDoubleUnion: Should have the right value at ${callsToForEachCallback} calls to forEach callback`);
+ is(this, thisArg,
+ "IterableDoubleUnion: Should have the right this value for forEach callback");
+ is(obj, itr,
+ "IterableSingle: Should have the right third arg for forEach callback");
+ ++callsToForEachCallback;
+ }, thisArg);
+ is(callsToForEachCallback, 2,
+ "IterableDoubleUnion: Should have right total number of calls to forEach callback");
+
+ key = key_itr.next();
+ value = value_itr.next();
+ entry = entries_itr.next();
+ is(key.value, undefined, "IterableDoubleUnion: Key iterator value should be undefined");
+ is(key.done, true, "IterableDoubleUnion: Key iterator done should be true");
+ is(value.value, undefined, "IterableDoubleUnion: Value iterator value should be undefined");
+ is(value.done, true, "IterableDoubleUnion: Value iterator done should be true");
+ is(entry.value, undefined, "IterableDoubleUnion: Entry iterator value should be undefined");
+ is(entry.done, true, "IterableDoubleUnion: Entry iterator done should be true");
+ is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)),
+ "[object TestInterfaceIterableDoubleUnion Iterator]",
+ "iterator prototype should have the right brand");
+
+ SimpleTest.finish();
+ });
+ </script>
+ </body>
+</html>
diff --git a/dom/bindings/test/test_jsimplemented_cross_realm_this.html b/dom/bindings/test/test_jsimplemented_cross_realm_this.html
new file mode 100644
index 0000000000..f44e3e02ae
--- /dev/null
+++ b/dom/bindings/test/test_jsimplemented_cross_realm_this.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1464374-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1464374</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=1464374">Mozilla Bug 1464374</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+
+<iframe></iframe>
+<script type="application/javascript">
+ /* global TestInterfaceJS */
+ /** Test for Bug 1464374 **/
+ SimpleTest.waitForExplicitFinish();
+
+ function doTest() {
+ var frame = frames[0];
+ var obj = new frame.TestInterfaceJS();
+ var ex;
+ try {
+ TestInterfaceJS.prototype.testThrowTypeError.call(obj);
+ } catch (e) {
+ ex = e;
+ }
+ ok(ex, "Should have an exception");
+ SimpleTest.finish();
+ }
+
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]},
+ doTest);
+</script>
+
+</body>
+</html>
diff --git a/dom/bindings/test/test_jsimplemented_eventhandler.html b/dom/bindings/test/test_jsimplemented_eventhandler.html
new file mode 100644
index 0000000000..7b77604744
--- /dev/null
+++ b/dom/bindings/test/test_jsimplemented_eventhandler.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1186696
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1186696</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+ /* global TestInterfaceJS */
+ /** Test for Bug 1186696 **/
+ SimpleTest.waitForExplicitFinish();
+
+ function doTest() {
+ var values = [ function() {}, 5, null, undefined, "some string", {} ];
+
+ while (values.length) {
+ var value = values.pop();
+ var t = new TestInterfaceJS();
+ t.onsomething = value;
+ var gottenValue = t.onsomething;
+ if (typeof value == "object" || typeof value == "function") {
+ is(gottenValue, value, "Should get back the object-or-null we put in");
+ } else {
+ is(gottenValue, null, "Should get back null");
+ }
+ }
+
+ SimpleTest.finish();
+ }
+
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]},
+ doTest);
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1186696">Mozilla Bug 1186696</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_jsimplemented_subclassing.html b/dom/bindings/test/test_jsimplemented_subclassing.html
new file mode 100644
index 0000000000..70be0d62aa
--- /dev/null
+++ b/dom/bindings/test/test_jsimplemented_subclassing.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1400275
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1400275</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1400275 **/
+ class Foo extends RTCPeerConnection {
+ }
+
+ var obj = new Foo();
+ is(Object.getPrototypeOf(obj), Foo.prototype,
+ "Should have the right prototype");
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1400275">Mozilla Bug 1400275</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_large_arraybuffers.html b/dom/bindings/test/test_large_arraybuffers.html
new file mode 100644
index 0000000000..64f6fc7276
--- /dev/null
+++ b/dom/bindings/test/test_large_arraybuffers.html
@@ -0,0 +1,97 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1688616
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for large ArrayBuffers and views</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=1688616">Mozilla Bug 1688616</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+ <script type="application/javascript">
+ /* global TestFunctions */
+
+ SimpleTest.waitForExplicitFinish();
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]}, go);
+
+ function checkThrowsTooLarge(f) {
+ let ex;
+ try{
+ f();
+ ok(false, "Should have thrown!");
+ } catch (e) {
+ ex = e;
+ }
+ ok(ex.toString().includes("larger than 2 GB"), "Got exception: " + ex);
+ }
+
+ function go() {
+ let test = new TestFunctions();
+
+ const gb = 1 * 1024 * 1024 * 1024;
+ let ab = new ArrayBuffer(5 * gb);
+ checkThrowsTooLarge(() => test.testNotAllowShared(ab));
+ checkThrowsTooLarge(() => test.testAllowShared(ab));
+ checkThrowsTooLarge(() => test.testDictWithAllowShared({arrayBuffer: ab}));
+ checkThrowsTooLarge(() => test.testUnionOfBuffferSource(ab));
+ checkThrowsTooLarge(() => { test.arrayBuffer = ab; });
+ checkThrowsTooLarge(() => { test.allowSharedArrayBuffer = ab; });
+ checkThrowsTooLarge(() => { test.sequenceOfArrayBuffer = [ab]; });
+ checkThrowsTooLarge(() => { test.sequenceOfAllowSharedArrayBuffer = [ab]; });
+
+ let ta = new Int8Array(ab, 0, 3 * gb);
+ checkThrowsTooLarge(() => test.testNotAllowShared(ta));
+ checkThrowsTooLarge(() => test.testAllowShared(ta));
+ checkThrowsTooLarge(() => test.testDictWithAllowShared({arrayBufferView: ta}));
+ checkThrowsTooLarge(() => test.testUnionOfBuffferSource(ta));
+ checkThrowsTooLarge(() => { test.arrayBufferView = ta; });
+ checkThrowsTooLarge(() => { test.allowSharedArrayBufferView = ta; });
+ checkThrowsTooLarge(() => { test.sequenceOfArrayBufferView = [ta]; });
+ checkThrowsTooLarge(() => { test.sequenceOfAllowSharedArrayBufferView = [ta]; });
+
+ let dv = new DataView(ab);
+ checkThrowsTooLarge(() => test.testNotAllowShared(dv));
+ checkThrowsTooLarge(() => test.testAllowShared(dv));
+ checkThrowsTooLarge(() => test.testDictWithAllowShared({arrayBufferView: dv}));
+ checkThrowsTooLarge(() => test.testUnionOfBuffferSource(dv));
+ checkThrowsTooLarge(() => { test.arrayBufferView = dv; });
+ checkThrowsTooLarge(() => { test.allowSharedArrayBufferView = dv; });
+ checkThrowsTooLarge(() => { test.sequenceOfArrayBufferView = [dv]; });
+ checkThrowsTooLarge(() => { test.sequenceOfAllowSharedArrayBufferView = [dv]; });
+
+ if (this.SharedArrayBuffer) {
+ let sab = new SharedArrayBuffer(5 * gb);
+ checkThrowsTooLarge(() => test.testAllowShared(sab));
+ checkThrowsTooLarge(() => test.testDictWithAllowShared({allowSharedArrayBuffer: sab}));
+ checkThrowsTooLarge(() => test.testUnionOfAllowSharedBuffferSource(sab));
+ checkThrowsTooLarge(() => { test.allowSharedArrayBuffer = sab; });
+ checkThrowsTooLarge(() => { test.sequenceOfAllowSharedArrayBuffer = [sab]; });
+
+ let sta = new Int8Array(sab);
+ checkThrowsTooLarge(() => test.testAllowShared(sta));
+ checkThrowsTooLarge(() => test.testDictWithAllowShared({allowSharedArrayBufferView: sta}));
+ checkThrowsTooLarge(() => test.testUnionOfAllowSharedBuffferSource(sta));
+ checkThrowsTooLarge(() => { test.allowSharedArrayBufferView = sta; });
+ checkThrowsTooLarge(() => { test.sequenceOfAllowSharedArrayBufferView = [sta]; });
+ }
+
+ // Small views on large buffers are fine.
+ let ta2 = new Int8Array(ab, 4 * gb);
+ is(ta2.byteLength, 1 * gb, "Small view on large ArrayBuffer");
+ test.testNotAllowShared(ta2);
+ test.arrayBufferView = ta2;
+
+ SimpleTest.finish();
+ }
+ </script>
+</body>
+</html>
diff --git a/dom/bindings/test/test_large_imageData.html b/dom/bindings/test/test_large_imageData.html
new file mode 100644
index 0000000000..68cb4bd50b
--- /dev/null
+++ b/dom/bindings/test/test_large_imageData.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1716622
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for large ImageData</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=1716622">Mozilla Bug 1716622</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+ <canvas id="canvas" width="800" height="800"></canvas>
+ <script type="application/javascript">
+ SimpleTest.waitForExplicitFinish();
+
+ function go() {
+ var ctx = document.getElementById("canvas").getContext("2d");
+
+ var ex = null;
+ try {
+ ctx.createImageData(23175, 23175);
+ } catch (e) {
+ ex = e;
+ }
+ ok(ex.toString().includes("Invalid width or height"),
+ "Expected createImageData exception");
+
+ ex = null;
+ try {
+ ctx.createImageData(33000, 33000);
+ } catch (e) {
+ ex = e;
+ }
+ ok(ex.toString().includes("Invalid width or height"),
+ "Expected createImageData exception");
+
+ ex = null;
+ try {
+ ctx.getImageData(0, 0, 23175, 23175);
+ } catch (e) {
+ ex = e;
+ }
+ ok(ex.toString().includes("negative or greater than the allowed amount"),
+ "Expected getImageData exception");
+
+ ex = null;
+ try {
+ new ImageData(23175, 23175);
+ } catch (e) {
+ ex = e;
+ }
+ ok(ex.toString().includes("negative or greater than the allowed amount"),
+ "Expected ImageData constructor exception");
+
+ SimpleTest.finish();
+ }
+ go();
+ </script>
+</body>
+</html>
diff --git a/dom/bindings/test/test_lenientThis.html b/dom/bindings/test/test_lenientThis.html
new file mode 100644
index 0000000000..f4fb4200a5
--- /dev/null
+++ b/dom/bindings/test/test_lenientThis.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>[LenientThis]</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+/* global test, assert_equals */
+function noop1() { }
+function noop2() { }
+
+test(function() {
+ var desc = Object.getOwnPropertyDescriptor(Document.prototype, "onreadystatechange");
+
+ document.onreadystatechange = noop1;
+ assert_equals(document.onreadystatechange, noop1, "document.onreadystatechange == noop1");
+ assert_equals(desc.get.call({ }), undefined, "document.onreadystatechange getter.call({}) == undefined");
+}, "invoking Document.onreadystatechange's getter with an invalid this object returns undefined");
+
+test(function() {
+ var desc = Object.getOwnPropertyDescriptor(Document.prototype, "onreadystatechange");
+
+ document.onreadystatechange = noop1;
+ assert_equals(document.onreadystatechange, noop1, "document.onreadystatechange == noop1");
+ assert_equals(desc.set.call({ }, noop2), undefined, "document.onreadystatechange setter.call({}) == undefined");
+ assert_equals(document.onreadystatechange, noop1, "document.onreadystatechange == noop1 (still)");
+}, "invoking Document.onreadystatechange's setter with an invalid this object does nothing and returns undefined");
+</script>
diff --git a/dom/bindings/test/test_lookupGetter.html b/dom/bindings/test/test_lookupGetter.html
new file mode 100644
index 0000000000..5fe15059b7
--- /dev/null
+++ b/dom/bindings/test/test_lookupGetter.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=462428
+-->
+<head>
+ <title>Test for Bug 462428</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=462428">Mozilla Bug 462428</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 462428 **/
+var x = new XMLHttpRequest;
+x.open("GET", "");
+var getter = x.__lookupGetter__("readyState");
+ok(getter !== undefined, "But able to look it up the normal way");
+ok(!x.hasOwnProperty("readyState"), "property should still be on the prototype");
+
+var sawProp = false;
+for (var i in x) {
+ if (i === "readyState") {
+ sawProp = true;
+ }
+}
+
+ok(sawProp, "property should be enumerable");
+
+is(getter.call(x), 1, "the getter actually works");
+
+Object.getPrototypeOf(x).__defineSetter__("readyState", function() {});
+is(getter.call(x), 1, "the getter works after defineSetter");
+
+is(x.responseType, "", "Should have correct responseType up front");
+var setter = x.__lookupSetter__("responseType");
+setter.call(x, "document");
+is(x.responseType, "document", "the setter is bound correctly");
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_namedNoIndexed.html b/dom/bindings/test/test_namedNoIndexed.html
new file mode 100644
index 0000000000..73a79d3894
--- /dev/null
+++ b/dom/bindings/test/test_namedNoIndexed.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=808991
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 808991</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=808991">Mozilla Bug 808991</a>
+<p id="display"></p>
+<div id="content" style="display: none" data-1="foo" data-bar="baz">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 808991 **/
+is($("content").dataset[1], "foo",
+ "Indexed props should work like named on dataset");
+is($("content").dataset["1"], "foo",
+ "Indexed props as strings should work like named on dataset");
+is($("content").dataset.bar, "baz",
+ "Named props should work on dataset");
+is($("content").dataset.bar, "baz",
+ "Named props as strings should work on dataset");
+
+
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_named_getter_enumerability.html b/dom/bindings/test/test_named_getter_enumerability.html
new file mode 100644
index 0000000000..3894633a3b
--- /dev/null
+++ b/dom/bindings/test/test_named_getter_enumerability.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Test for named getter enumerability</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+/* global test, assert_equals, assert_true, assert_false, assert_not_equals */
+test(function() {
+ var list = document.getElementsByTagName("div");
+ var desc = Object.getOwnPropertyDescriptor(list, "0");
+ assert_equals(typeof desc, "object", "Should have a '0' property");
+ assert_true(desc.enumerable, "'0' property should be enumerable");
+ desc = Object.getOwnPropertyDescriptor(list, "log");
+ assert_equals(typeof desc, "object", "Should have a 'log' property");
+ assert_false(desc.enumerable, "'log' property should not be enumerable");
+}, "Correct getOwnPropertyDescriptor behavior");
+test(function() {
+ var list = document.getElementsByTagName("div");
+ var props = [];
+ for (var prop in list) {
+ props.push(prop);
+ }
+ assert_not_equals(props.indexOf("0"), -1, "Should enumerate '0'");
+ assert_equals(props.indexOf("log"), -1, "Should not enumerate 'log'");
+}, "Correct enumeration behavior");
+test(function() {
+ var list = document.getElementsByTagName("div");
+ var props = Object.keys(list);
+ assert_not_equals(props.indexOf("0"), -1, "Keys should contain '0'");
+ assert_equals(props.indexOf("log"), -1, "Keys should not contain 'log'");
+}, "Correct keys() behavior");
+test(function() {
+ var list = document.getElementsByTagName("div");
+ var props = Object.getOwnPropertyNames(list);
+ assert_not_equals(props.indexOf("0"), -1,
+ "own prop names should contain '0'");
+ assert_not_equals(props.indexOf("log"), -1,
+ "own prop names should contain 'log'");
+}, "Correct getOwnPropertyNames() behavior");
+</script>
diff --git a/dom/bindings/test/test_observablearray.html b/dom/bindings/test/test_observablearray.html
new file mode 100644
index 0000000000..313fb67622
--- /dev/null
+++ b/dom/bindings/test/test_observablearray.html
@@ -0,0 +1,546 @@
+<!-- Any copyright is dedicated to the Public Domain.
+- http://creativecommons.org/publicdomain/zero/1.0/ -->
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>Test Observable Array Type</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<script>
+/* global TestInterfaceObservableArray */
+
+add_task(async function init() {
+ await SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]});
+});
+
+add_task(function testObservableArray_length() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+ let deleteCallbackTests = null;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (typeof deleteCallbackTests === 'function') {
+ deleteCallbackTests(value, index);
+ }
+ },
+ });
+ m.observableArrayBoolean = [true, true, true, true, true];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 5, "length of observable array should be 5");
+
+ [
+ // [length, shouldThrow, expectedResult]
+ ["invalid", true, false],
+ [b.length + 1, false, false],
+ [b.length, false, true],
+ [b.length - 1, false, true],
+ [0, false, true],
+ ].forEach(function([length, shouldThrow, expectedResult]) {
+ // Initialize
+ let oldValues = b.slice();
+ let oldLen = b.length;
+ let shouldSuccess = !shouldThrow && expectedResult;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ deleteCallbackTests = null;
+ if (shouldSuccess) {
+ let deleteCallbackIndex = b.length - 1;
+ deleteCallbackTests = function(_value, _index) {
+ info(`delete callback for ${_index}`);
+ is(_value, oldValues[deleteCallbackIndex], "deleteCallbackTests: test value argument");
+ is(_index, deleteCallbackIndex, "deleteCallbackTests: test index argument");
+ deleteCallbackIndex--;
+ };
+ }
+
+ // Test
+ info(`setting length to ${length}`);
+ try {
+ b.length = length;
+ ok(!shouldThrow, `setting length should throw`);
+ } catch(e) {
+ ok(shouldThrow, `setting length throws ${e}`);
+ }
+ is(setCallbackCount, 0, "setCallback should not be called");
+ is(deleteCallbackCount, shouldSuccess ? (oldLen - length) : 0, "deleteCallback count");
+ isDeeply(b, shouldSuccess ? oldValues.slice(0, length) : oldValues, "property values");
+ is(b.length, shouldSuccess ? length : oldLen, `length of observable array`);
+ });
+});
+
+add_task(function testObservableArray_length_callback_throw() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (value) {
+ throw new Error("deleteBooleanCallback");
+ }
+ },
+ });
+ m.observableArrayBoolean = [true, true, false, false, false];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 5, "length of observable array should be 5");
+
+ // Initialize
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`setting length to 0`);
+ try {
+ b.length = 0;
+ ok(false, `setting length should throw`);
+ } catch(e) {
+ ok(true, `setting length throws ${e}`);
+ }
+ is(setCallbackCount, 0, "setCallback should not be called");
+ is(deleteCallbackCount, 4, "deleteCallback should be called");
+ isDeeply(b, [true, true], "property values");
+ is(b.length, 2, `length of observable array`);
+});
+
+add_task(function testObservableArray_setter() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+ let setCallbackTests = null;
+ let deleteCallbackTests = null;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ if (typeof setCallbackTests === 'function') {
+ setCallbackTests(value, index);
+ }
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (typeof deleteCallbackTests === 'function') {
+ deleteCallbackTests(value, index);
+ }
+ },
+ });
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 0, "length of observable array should be 0");
+
+ [
+ // [values, shouldThrow]
+ ["invalid", true],
+ [[1,[],{},"invalid"], false],
+ [[0,NaN,null,undefined,""], false],
+ [[true,true], false],
+ [[false,false,false], false],
+ ].forEach(function([values, shouldThrow]) {
+ // Initialize
+ let oldValues = b.slice();
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ setCallbackTests = null;
+ deleteCallbackTests = null;
+ if (!shouldThrow) {
+ let setCallbackIndex = 0;
+ setCallbackTests = function(_value, _index) {
+ info(`set callback for ${_index}`);
+ is(_value, !!values[setCallbackIndex], "setCallbackTests: test value argument");
+ is(_index, setCallbackIndex, "setCallbackTests: test index argument");
+ setCallbackIndex++;
+ };
+
+ let deleteCallbackIndex = b.length - 1;
+ deleteCallbackTests = function(_value, _index) {
+ info(`delete callback for ${_index}`);
+ is(_value, oldValues[deleteCallbackIndex], "deleteCallbackTests: test value argument");
+ is(_index, deleteCallbackIndex, "deleteCallbackTests: test index argument");
+ deleteCallbackIndex--;
+ };
+ }
+
+ // Test
+ info(`setting value to ${JSON.stringify(values)}`);
+ try {
+ m.observableArrayBoolean = values;
+ ok(!shouldThrow, `setting value should not throw`);
+ } catch(e) {
+ ok(shouldThrow, `setting value throws ${e}`);
+ }
+ is(setCallbackCount, shouldThrow ? 0 : values.length, "setCallback count");
+ is(deleteCallbackCount, oldLen, "deleteCallback should be called");
+ isDeeply(b, shouldThrow ? [] : values.map(v => !!v), "property values");
+ is(b.length, shouldThrow ? 0 : values.length, `length of observable array`);
+ });
+});
+
+add_task(function testObservableArray_setter_invalid_item() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+ let setCallbackTests = null;
+ let deleteCallbackTests = null;
+
+ let m = new TestInterfaceObservableArray({
+ setInterfaceCallback(value, index) {
+ setCallbackCount++;
+ if (typeof setCallbackTests === 'function') {
+ setCallbackTests(value, index);
+ }
+ },
+ deleteInterfaceCallback(value, index) {
+ deleteCallbackCount++;
+ if (typeof deleteCallbackTests === 'function') {
+ deleteCallbackTests(value, index);
+ }
+ },
+ });
+
+ let b = m.observableArrayInterface;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 0, "length of observable array should be 0");
+
+ [
+ // [values, shouldThrow]
+ [[m,m,m,m], false],
+ [["invalid"], true],
+ [[m,m], false],
+ [[m,"invalid"], true],
+ [[m,m,m], false],
+ ].forEach(function([values, shouldThrow]) {
+ // Initialize
+ let oldValues = b.slice();
+ let oldLen = b.length;
+ let setCallbackIndex = 0;
+ setCallbackTests = function(_value, _index) {
+ info(`set callback for ${_index}`);
+ is(_value, values[setCallbackIndex], "setCallbackTests: test value argument");
+ is(_index, setCallbackIndex, "setCallbackTests: test index argument");
+ setCallbackIndex++;
+ };
+ let deleteCallbackIndex = b.length - 1;
+ deleteCallbackTests = function(_value, _index) {
+ info(`delete callback for ${_index}`);
+ is(_value, oldValues[deleteCallbackIndex], "deleteCallbackTests: test value argument");
+ is(_index, deleteCallbackIndex, "deleteCallbackTests: test index argument");
+ deleteCallbackIndex--;
+ };
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`setting value to ${values}`);
+ try {
+ m.observableArrayInterface = values;
+ ok(!shouldThrow, `setting value should not throw`);
+ } catch(e) {
+ ok(shouldThrow, `setting value throws ${e}`);
+ }
+ is(setCallbackCount, shouldThrow ? 0 : values.length, "setCallback count");
+ is(deleteCallbackCount, shouldThrow ? 0 : oldLen, "deleteCallback should be called");
+ isDeeply(b, shouldThrow ? oldValues : values, "property values");
+ is(b.length, shouldThrow ? oldLen : values.length, `length of observable array`);
+ });
+});
+
+add_task(function testObservableArray_setter_callback_throw() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ if (index >= 3) {
+ throw new Error("setBooleanCallback");
+ }
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (value) {
+ throw new Error("deleteBooleanCallback");
+ }
+ },
+ });
+ m.observableArrayBoolean = [false, false, false];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 3, "length of observable array should be 3");
+
+ [
+ // [values, shouldThrow, expectedLength, expectedSetCbCount, expectedDeleteCbCount]
+ [[false,false], false, 2, 2, 3],
+ [[false,true,false,false], true, 3, 4, 2],
+ [[false,false,true], true, 2, 0, 2],
+ ].forEach(function([values, shouldThrow, expectedLength, expectedSetCbCount,
+ expectedDeleteCbCount]) {
+ // Initialize
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`setting value to ${values}`);
+ try {
+ m.observableArrayBoolean = values;
+ ok(!shouldThrow, `setting value should not throw`);
+ } catch(e) {
+ ok(shouldThrow, `setting length throws ${e}`);
+ }
+ is(setCallbackCount, expectedSetCbCount, "setCallback should be called");
+ is(deleteCallbackCount, expectedDeleteCbCount, "deleteCallback should be called");
+ is(b.length, expectedLength, `length of observable array`);
+ });
+});
+
+add_task(function testObservableArray_indexed_setter() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+ let setCallbackTests = null;
+ let deleteCallbackTests = null;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ if (typeof setCallbackTests === 'function') {
+ setCallbackTests(value, index);
+ }
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (typeof deleteCallbackTests === 'function') {
+ deleteCallbackTests(value, index);
+ }
+ },
+ });
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 0, "length of observable array should be 0");
+
+ [
+ // [index, value, expectedResult]
+ [b.length + 1, false, false],
+ [b.length, false, true],
+ [b.length + 1, false, true],
+ [b.length + 1, true, true],
+ ].forEach(function([index, value, expectedResult]) {
+ // Initialize
+ let oldValue = b[index];
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ setCallbackTests = function(_value, _index) {
+ info(`set callback for ${_index}`);
+ is(_value, value, "setCallbackTests: test value argument");
+ is(_index, index, "setCallbackTests: test index argument");
+ };
+ deleteCallbackTests = function(_value, _index) {
+ info(`delete callback for ${_index}`);
+ is(_value, oldValue, "deleteCallbackTests: test value argument");
+ is(_index, index, "deleteCallbackTests: test index argument");
+ };
+
+ // Test
+ info(`setting value of property ${index} to ${value}`);
+ try {
+ b[index] = value;
+ ok(true, `setting value should not throw`);
+ } catch(e) {
+ ok(false, `setting value throws ${e}`);
+ }
+ is(setCallbackCount, expectedResult ? 1 : 0, "setCallback should be called");
+ is(deleteCallbackCount, (oldLen > index) ? 1 : 0, "deleteCallback should be called");
+ is(b[index], expectedResult ? value : oldValue, `property value`);
+ is(b.length, expectedResult ? Math.max(oldLen, index + 1) : oldLen, `length of observable array`);
+ });
+});
+
+add_task(function testObservableArray_indexed_setter_invalid() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+ let setCallbackTests = null;
+ let deleteCallbackTests = null;
+
+ let m = new TestInterfaceObservableArray({
+ setInterfaceCallback(value, index) {
+ setCallbackCount++;
+ if (typeof setCallbackTests === 'function') {
+ setCallbackTests(value, index);
+ }
+ },
+ deleteInterfaceCallback(value, index) {
+ deleteCallbackCount++;
+ if (typeof deleteCallbackTests === 'function') {
+ deleteCallbackTests(value, index);
+ }
+ },
+ });
+
+ let b = m.observableArrayInterface;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 0, "length of observable array should be 0");
+
+ [
+ // [index, value, shouldThrow]
+ [b.length, "invalid", true],
+ [b.length, m, false],
+ [b.length + 1, m, false],
+ [b.length + 1, "invalid", true],
+ ].forEach(function([index, value, shouldThrow]) {
+ // Initialize
+ let oldValue = b[index];
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ setCallbackTests = function(_value, _index) {
+ info(`set callback for ${_index}`);
+ is(_value, value, "setCallbackTests: test value argument");
+ is(_index, index, "setCallbackTests: test index argument");
+ };
+ deleteCallbackTests = function(_value, _index) {
+ info(`delete callback for ${_index}`);
+ is(_value, oldValue, "deleteCallbackTests: test value argument");
+ is(_index, index, "deleteCallbackTests: test index argument");
+ };
+
+ // Test
+ info(`setting value of property ${index} to ${value}`);
+ try {
+ b[index] = value;
+ ok(!shouldThrow, `setting value should not throw`);
+ } catch(e) {
+ ok(shouldThrow, `setting value throws ${e}`);
+ }
+ is(setCallbackCount, shouldThrow ? 0 : 1, "setCallback count");
+ is(deleteCallbackCount, ((oldLen > index) && !shouldThrow) ? 1 : 0, "deleteCallback count");
+ is(b[index], shouldThrow ? oldValue : value, `property value`);
+ is(b.length, shouldThrow ? oldLen : Math.max(oldLen, index + 1), `length of observable array`);
+ });
+});
+
+add_task(function testObservableArray_indexed_setter_callback_throw() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ if (value) {
+ throw new Error("setBooleanCallback");
+ }
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (index < 2) {
+ throw new Error("deleteBooleanCallback");
+ }
+ },
+ });
+ m.observableArrayBoolean = [false, false, false];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 3, "length of observable array should be 3");
+
+ [
+ // [index, value, shouldThrow]
+ [b.length, true, true],
+ [b.length, false, false],
+ [b.length, true, true],
+ [0, false, true],
+ [0, true, true]
+ ].forEach(function([index, value, shouldThrow]) {
+ // Initialize
+ let oldValue = b[index];
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`setting value of property ${index} to ${value}`);
+ try {
+ b[index] = value;
+ ok(!shouldThrow, `setting value should not throw`);
+ } catch(e) {
+ ok(shouldThrow, `setting value throws ${e}`);
+ }
+ is(setCallbackCount, (shouldThrow && index < 2) ? 0 : 1, "setCallback should be called");
+ is(deleteCallbackCount, (oldLen > index) ? 1 : 0, "deleteCallback should be called");
+ is(b[index], shouldThrow ? oldValue : value, "property value");
+ is(b.length, shouldThrow ? oldLen : Math.max(oldLen, index + 1), `length of observable array`);
+ });
+});
+
+add_task(function testObservableArray_object() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+ let callbackIndex = 0;
+
+ let values = [
+ {property1: false, property2: "property2"},
+ {property1: [], property2: 2},
+ ];
+
+ let m = new TestInterfaceObservableArray({
+ setObjectCallback(value, index) {
+ setCallbackCount++;
+ is(index, callbackIndex++, "setCallbackTests: test index argument");
+ isDeeply(values[index], value, "setCallbackTests: test value argument");
+ },
+ deleteObjectCallback(value, index) {
+ deleteCallbackCount++;
+ },
+ });
+
+ m.observableArrayObject = values;
+
+ let b = m.observableArrayObject;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 2, "length of observable array should be 2");
+ is(setCallbackCount, values.length, "setCallback should be called");
+ is(deleteCallbackCount, 0, "deleteCallback should not be called");
+
+ for(let i = 0; i < values.length; i++) {
+ isDeeply(values[i], b[i], `check index ${i}`);
+ }
+});
+
+add_task(function testObservableArray_xrays() {
+ let m = new TestInterfaceObservableArray({
+ setObjectCallback(value, index) {
+ ok(false, "Shouldn't reach setObjectCallback");
+ },
+ deleteObjectCallback(value, index) {
+ ok(false, "Shouldn't reach deleteObjectCallback");
+ },
+ });
+
+ let wrapper = SpecialPowers.wrap(m);
+ ok(SpecialPowers.Cu.isXrayWrapper(wrapper), "Should be a wrapper");
+ let observableArray = wrapper.observableArrayBoolean;
+ ok(!!observableArray, "Should not throw");
+ is("length" in observableArray, false, "Should be opaque");
+
+ try {
+ wrapper.observableArrayBoolean = [true, false, false];
+ ok(false, "Expected to throw, for now");
+ } catch (ex) {}
+});
+
+</script>
+</body>
+</html>
diff --git a/dom/bindings/test/test_observablearray_helper.html b/dom/bindings/test/test_observablearray_helper.html
new file mode 100644
index 0000000000..d2b4897cac
--- /dev/null
+++ b/dom/bindings/test/test_observablearray_helper.html
@@ -0,0 +1,376 @@
+<!-- Any copyright is dedicated to the Public Domain.
+- http://creativecommons.org/publicdomain/zero/1.0/ -->
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>Test Helpers of Observable Array Type</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<script>
+/* global TestInterfaceObservableArray */
+
+add_task(async function init() {
+ await SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]});
+});
+
+add_task(function testObservableArray_helper_elementAt() {
+ let m = new TestInterfaceObservableArray();
+
+ [
+ // [values, property, helper]
+ [[true, false], "observableArrayBoolean", m.booleanElementAtInternal.bind(m)],
+ [[new TestInterfaceObservableArray(), new TestInterfaceObservableArray()],
+ "observableArrayInterface", m.interfaceElementAtInternal.bind(m)],
+ [[{property: "test"}, {property: 2}], "observableArrayObject",
+ m.objectElementAtInternal.bind(m)],
+ ].forEach(function([values, property, helper]) {
+ m[property] = values;
+
+ let t = m[property];
+ ok(Array.isArray(t), "observable array should be an array type");
+ is(t.length, values.length, "length of observable array");
+
+ for (let i = 0; i < values.length; i++) {
+ isDeeply(values[i], helper(i), `check index ${i}`);
+ }
+
+ SimpleTest.doesThrow(() => {
+ helper(values.length);
+ }, `getting element outside the range should throw`);
+ });
+});
+
+add_task(function testObservableArray_helper_replaceElementAt() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+ let setCallbackTests = null;
+ let deleteCallbackTests = null;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ if (typeof setCallbackTests === 'function') {
+ setCallbackTests(value, index);
+ }
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (typeof deleteCallbackTests === 'function') {
+ deleteCallbackTests(value, index);
+ }
+ },
+ });
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 0, "length of observable array should be 0");
+
+ [
+ // [index, value, shouldThrow]
+ [b.length + 1, false, true],
+ [b.length, false, false],
+ [b.length + 1, false, false],
+ [b.length + 1, true, false],
+ ].forEach(function([index, value, shouldThrow]) {
+ // Initialize
+ let oldValue = b[index];
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ setCallbackTests = function(_value, _index) {
+ info(`set callback for ${_index}`);
+ is(_value, value, "setCallbackTests: test value argument");
+ is(_index, index, "setCallbackTests: test index argument");
+ };
+ deleteCallbackTests = function(_value, _index) {
+ info(`delete callback for ${_index}`);
+ is(_value, oldValue, "deleteCallbackTests: test value argument");
+ is(_index, index, "deleteCallbackTests: test index argument");
+ };
+
+ // Test
+ info(`setting value of property ${index} to ${value}`);
+ try {
+ m.booleanReplaceElementAtInternal(index, value);
+ ok(!shouldThrow, `setting value should not throw`);
+ } catch(e) {
+ ok(shouldThrow, `setting value throws ${e}`);
+ }
+ is(setCallbackCount, shouldThrow ? 0 : 1, "setCallback count");
+ is(deleteCallbackCount, (oldLen > index) ? 1 : 0, "deleteCallback count");
+ is(b[index], shouldThrow ? oldValue : value, `property value`);
+ is(b.length, shouldThrow ? oldLen : Math.max(oldLen, index + 1), `length of observable array`);
+ });
+});
+
+add_task(function testObservableArray_helper_replaceElementAt_callback_throw() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ if (value) {
+ throw new Error("setBooleanCallback");
+ }
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (index < 2) {
+ throw new Error("deleteBooleanCallback");
+ }
+ },
+ });
+ m.observableArrayBoolean = [false, false, false];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 3, "length of observable array should be 3");
+
+ [
+ // [index, value, shouldThrow]
+ [b.length, true, true],
+ [b.length, false, false],
+ [b.length, true, true],
+ [0, false, true],
+ [0, true, true]
+ ].forEach(function([index, value, shouldThrow]) {
+ // Initialize
+ let oldValue = b[index];
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`setting value of property ${index} to ${value}`);
+ try {
+ m.booleanReplaceElementAtInternal(index, value);
+ ok(!shouldThrow, `setting value should not throw`);
+ } catch(e) {
+ ok(shouldThrow, `setting value throws ${e}`);
+ }
+ is(setCallbackCount, (shouldThrow && index < 2) ? 0 : 1, "setCallback count");
+ is(deleteCallbackCount, (oldLen > index) ? 1 : 0, "deleteCallback count");
+ is(b[index], shouldThrow ? oldValue : value, "property value");
+ is(b.length, shouldThrow ? oldLen : Math.max(oldLen, index + 1), `length of observable array`);
+ });
+});
+
+add_task(function testObservableArray_helper_appendElement() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+ let setCallbackTests = null;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ if (typeof setCallbackTests === 'function') {
+ setCallbackTests(value, index);
+ }
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ },
+ });
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 0, "length of observable array should be 0");
+
+ [true, false, true, false].forEach(function(value) {
+ // Initialize
+ let oldLen = b.length;
+ let index = oldLen;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ setCallbackTests = function(_value, _index) {
+ info(`set callback for ${_index}`);
+ is(_value, value, "setCallbackTests: test value argument");
+ is(_index, index, "setCallbackTests: test index argument");
+ };
+
+ // Test
+ info(`append ${value}`);
+ try {
+ m.booleanAppendElementInternal(value);
+ ok(true, `appending value should not throw`);
+ } catch(e) {
+ ok(false, `appending value throws ${e}`);
+ }
+ is(setCallbackCount, 1, "setCallback should be called");
+ is(deleteCallbackCount, 0, "deleteCallback should not be called");
+ is(b[index], value, `property value`);
+ is(b.length, oldLen + 1, `length of observable array`);
+ });
+});
+
+add_task(function testObservableArray_helper_appendElement_callback_throw() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ if (value) {
+ throw new Error("setBooleanCallback");
+ }
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ },
+ });
+ m.observableArrayBoolean = [false, false, false];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 3, "length of observable array should be 3");
+
+ [true, false, true, false].forEach(function(value) {
+ // Initialize
+ let oldLen = b.length;
+ let index = oldLen;
+ let oldValue = b[index];
+ let shouldThrow = value;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`append ${value}`);
+ try {
+ m.booleanAppendElementInternal(value);
+ ok(!shouldThrow, `appending value should not throw`);
+ } catch(e) {
+ ok(shouldThrow, `appending value throws ${e}`);
+ }
+ is(setCallbackCount, 1, "setCallback should be called");
+ is(deleteCallbackCount, 0, "deleteCallback should not be called");
+ is(b[index], shouldThrow ? oldValue : value, "property value");
+ is(b.length, shouldThrow ? oldLen : oldLen + 1, `length of observable array`);
+ });
+});
+
+add_task(function testObservableArray_helper_removeLastElement() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+ let deleteCallbackTests = null;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (typeof deleteCallbackTests === 'function') {
+ deleteCallbackTests(value, index);
+ }
+ },
+ });
+ m.observableArrayBoolean = [true, false, true, false];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 4, "length of observable array should be 4");
+
+ let oldValues = b.slice();
+ while (oldValues.length) {
+ // Initialize
+ let oldValue = oldValues.pop();
+ let index = oldValues.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ deleteCallbackTests = function(_value, _index) {
+ info(`delete callback for ${_index}`);
+ is(_value, oldValue, "deleteCallbackTests: test value argument");
+ is(_index, index, "deleteCallbackTests: test index argument");
+ };
+
+ // Test
+ info(`remove last element`);
+ try {
+ m.booleanRemoveLastElementInternal();
+ ok(true, `removing last element should not throw`);
+ } catch(e) {
+ ok(false, `removing last element throws ${e}`);
+ }
+ is(setCallbackCount, 0, "setCallback should not be called");
+ is(deleteCallbackCount, 1, "deleteCallback should be called");
+ isDeeply(b, oldValues, `property value`);
+ is(b.length, oldValues.length, `length of observable array`);
+ }
+
+ // test when array is empty
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ SimpleTest.doesThrow(() => {
+ m.booleanRemoveLastElementInternal();
+ }, `removing last element should throw when array is empty`);
+ is(setCallbackCount, 0, "setCallback should not be called");
+ is(deleteCallbackCount, 0, "deleteCallback should not be called");
+ is(b.length, 0, `length of observable array`);
+});
+
+add_task(function testObservableArray_helper_removeLastElement_callback_throw() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (value) {
+ throw new Error("deleteBooleanCallback");
+ }
+ },
+ });
+ m.observableArrayBoolean = [false, true, false, false];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 4, "length of observable array should be 4");
+
+ let shouldThrow = false;
+ while (!shouldThrow && b.length) {
+ // Initialize
+ let oldValues = b.slice();
+ let oldLen = b.length;
+ shouldThrow = oldValues[oldLen - 1];
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`remove last element`);
+ try {
+ m.booleanRemoveLastElementInternal();
+ ok(!shouldThrow, `removing last element should not throw`);
+ } catch(e) {
+ ok(shouldThrow, `removing last element throws ${e}`);
+ }
+ is(setCallbackCount, 0, "setCallback should not be called");
+ is(deleteCallbackCount, 1, "deleteCallback should be called");
+ isDeeply(b, shouldThrow ? oldValues : oldValues.slice(0, oldLen - 1), `property value`);
+ is(b.length, shouldThrow ? oldLen : oldLen - 1, `length of observable array`);
+ }
+});
+
+add_task(function testObservableArray_helper_length() {
+ let m = new TestInterfaceObservableArray();
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 0, "length of observable array");
+
+ [
+ [false, true, false, true],
+ [true, false],
+ [false, true, false],
+ ].forEach(function(values) {
+ m.observableArrayBoolean = values;
+ is(b.length, m.booleanLengthInternal(), "length helper function");
+ });
+});
+</script>
+</body>
+</html>
diff --git a/dom/bindings/test/test_observablearray_proxyhandler.html b/dom/bindings/test/test_observablearray_proxyhandler.html
new file mode 100644
index 0000000000..d7d8810981
--- /dev/null
+++ b/dom/bindings/test/test_observablearray_proxyhandler.html
@@ -0,0 +1,859 @@
+<!-- Any copyright is dedicated to the Public Domain.
+- http://creativecommons.org/publicdomain/zero/1.0/ -->
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>Test Observable Array Type</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<script>
+/* global TestInterfaceObservableArray */
+
+add_task(async function init() {
+ await SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]});
+});
+
+add_task(function testObservableArrayExoticObjects_defineProperty() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+ let setCallbackTests = null;
+ let deleteCallbackTests = null;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ if (typeof setCallbackTests === 'function') {
+ setCallbackTests(value, index);
+ }
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (typeof deleteCallbackTests === 'function') {
+ deleteCallbackTests(value, index);
+ }
+ },
+ });
+ m.observableArrayBoolean = [true, true, true];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 3, "length of observable array should be 0");
+
+ // Test length
+ [
+ // [descriptor, shouldThrow, expectedResult]
+ // Invalid descriptor
+ [{configurable: true, value: 0}, false, false],
+ [{enumerable: true, value: 0}, false, false],
+ [{writable: false, value: 0}, false, false],
+ [{get: ()=>{}}, false, false],
+ [{set: ()=>{}}, false, false],
+ [{get: ()=>{}, set: ()=>{}}, false, false],
+ [{get: ()=>{}, value: 0}, true],
+ // Invalid length value
+ [{value: 1.9}, true],
+ [{value: "invalid"}, true],
+ [{value: {}}, true],
+ // length value should not greater than current length
+ [{value: b.length + 1}, false, false],
+ // descriptor without value
+ [{configurable: false, enumerable: false, writable: true}, false, true],
+ // Success
+ [{value: b.length}, false, true],
+ [{value: b.length - 1}, false, true],
+ [{value: 0}, false, true],
+ ].forEach(function([descriptor, shouldThrow, expectedResult]) {
+ // Initialize
+ let oldLen = b.length;
+ let oldValues = b.slice();
+ let deleteCallbackIndex = oldLen - 1;
+ let success = expectedResult && "value" in descriptor;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ setCallbackTests = null;
+ deleteCallbackTests = function(_value, _index) {
+ is(_value, oldValues[deleteCallbackIndex], "deleteCallbackTests: test value argument");
+ is(_index, deleteCallbackIndex, "deleteCallbackTests: test index argument");
+ deleteCallbackIndex--;
+ };
+
+ // Test
+ info(`defining "length" property with ${JSON.stringify(descriptor)}`);
+ try {
+ is(Reflect.defineProperty(b, "length", descriptor), expectedResult,
+ `Reflect.defineProperty should return ${expectedResult}`);
+ ok(!shouldThrow, "Reflect.defineProperty should not throw");
+ } catch(e) {
+ ok(shouldThrow, `Reflect.defineProperty throws ${e}`);
+ }
+ is(setCallbackCount, 0, "setCallback count");
+ is(deleteCallbackCount, success ? oldLen - descriptor.value : 0, "deleteCallback count");
+ isDeeply(b, success ? oldValues.slice(0, descriptor.value) : oldValues, "property values");
+ is(b.length, success ? descriptor.value : oldLen, "length of observable array");
+ });
+
+ // Test indexed value
+ [
+ // [index, descriptor, shouldThrow, expectedResult]
+ // Invalid descriptor
+ [0, {configurable: false, value: true}, false, false],
+ [0, {enumerable: false, value: true}, false, false],
+ [0, {writable: false, value: true}, false, false],
+ [0, {get: ()=>{}}, false, false],
+ [0, {set: ()=>{}}, false, false],
+ [0, {get: ()=>{}, set: ()=>{}}, false, false],
+ [0, {get: ()=>{}, value: true}, true],
+ // Index could not greater than last index + 1.
+ [b.length + 1, {configurable: true, enumerable: true, value: true}, false, false],
+ // descriptor without value
+ [b.length, {configurable: true, enumerable: true}, false, true],
+ // Success
+ [b.length, {configurable: true, enumerable: true, value: true}, false, true],
+ [b.length + 1, {configurable: true, enumerable: true, value: true}, false, true],
+ ].forEach(function([index, descriptor, shouldThrow, expectedResult]) {
+ // Initialize
+ let oldLen = b.length;
+ let oldValue = b[index];
+ let success = expectedResult && "value" in descriptor;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ setCallbackTests = function(_value, _index) {
+ is(_value, descriptor.value, "setCallbackTests: test value argument");
+ is(_index, index, "setCallbackTests: test index argument");
+ };
+ deleteCallbackTests = function(_value, _index) {
+ is(_value, oldValue, "deleteCallbackTests: test value argument");
+ is(_index, index, "deleteCallbackTests: test index argument");
+ };
+
+ // Test
+ info(`defining ${index} property with ${JSON.stringify(descriptor)}`);
+ try {
+ is(Reflect.defineProperty(b, index, descriptor), expectedResult,
+ `Reflect.defineProperty should return ${expectedResult}`);
+ ok(!shouldThrow, "Reflect.defineProperty should not throw");
+ } catch(e) {
+ ok(shouldThrow, `Reflect.defineProperty throws ${e}`);
+ }
+ is(setCallbackCount, success ? 1 : 0, "setCallback count");
+ is(deleteCallbackCount, (oldLen > index) ? 1 : 0, "deleteCallback count");
+ is(b[index], success ? descriptor.value : oldValue, "property value");
+ is(b.length, success ? Math.max(index + 1, oldLen) : oldLen, "length of observable array");
+ });
+
+ // Test other property
+ [
+ // [property, descriptor, shouldThrow, expectedResult]
+ ["prop1", {configurable: false, value: "value1"}, false, true],
+ ["prop1", {configurable: true, value: "value2"}, false, false],
+ ["prop2", {enumerable: false, value: 5}, false, true],
+ ["prop3", {enumerable: false, value: []}, false, true],
+ ["prop4", {enumerable: false, value: {}}, false, true],
+ ["prop5", {get: ()=>{}, value: true}, true, false],
+ ["prop6", {get: ()=>{}, set: ()=>{}}, false, true],
+ ].forEach(function([property, descriptor, shouldThrow, expectedResult]) {
+ // Initialize
+ let oldValue = b[property];
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ setCallbackTests = null;
+ deleteCallbackTests = null;
+
+ // Test
+ info(`defining ${property} property with ${JSON.stringify(descriptor)}`);
+ try {
+ is(Reflect.defineProperty(b, property, descriptor), expectedResult,
+ `Reflect.defineProperty should return ${expectedResult}`);
+ ok(!shouldThrow, "Reflect.defineProperty should not throw");
+ } catch(e) {
+ ok(shouldThrow, `Reflect.defineProperty throws ${e}`);
+ }
+ is(setCallbackCount, 0, "setCallback count");
+ is(deleteCallbackCount, 0, "deleteCallback count");
+ is(b[property], expectedResult ? descriptor.value : oldValue, "property value");
+ is(b.length, oldLen, "length of observable array");
+ });
+});
+
+add_task(function testObservableArrayExoticObjects_defineProperty_callback_throw() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+
+ const minLen = 3;
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ if (value) {
+ throw new Error("setBooleanCallback");
+ }
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (index < minLen) {
+ throw new Error("deleteBooleanCallback");
+ }
+ },
+ });
+ m.observableArrayBoolean = [false, false, false, false, false];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 5, "length of observable array should be 3");
+
+ // Test length
+ [
+ // [length, shouldThrow]
+ [b.length, false],
+ [b.length - 1, false],
+ [0, true],
+ ].forEach(function([length, shouldThrow]) {
+ // Initialize
+ let oldValues = b.slice();
+ let oldLen = b.length;
+ let descriptor = {value: length};
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`defining "length" property with ${JSON.stringify(descriptor)}`);
+ try {
+ ok(Reflect.defineProperty(b, "length", descriptor),
+ "Reflect.defineProperty should return true");
+ ok(!shouldThrow, "Reflect.defineProperty should not throw");
+ } catch(e) {
+ ok(shouldThrow, `Reflect.defineProperty throws ${e}`);
+ }
+ is(setCallbackCount, 0, "setCallback count");
+ is(deleteCallbackCount, oldLen - (shouldThrow ? minLen - 1 : length), "deleteCallback count");
+ isDeeply(b, oldValues.slice(0, shouldThrow ? minLen : length), "property values");
+ is(b.length, shouldThrow ? minLen : length, "length of observable array");
+ });
+
+ // Test indexed value
+ [
+ // [index, value, shouldThrow]
+ [b.length, true, true],
+ [b.length, false, false],
+ [b.length + 1, false, false],
+ [b.length + 1, true, true],
+ [0, true, true],
+ [0, false, true],
+ ].forEach(function([index, value, shouldThrow]) {
+ // Initialize
+ let oldValue = b[index];
+ let oldLen = b.length;
+ let descriptor = {configurable: true, enumerable: true, value};
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`defining ${index} property with ${JSON.stringify(descriptor)}`);
+ try {
+ ok(Reflect.defineProperty(b, index, descriptor), "Reflect.defineProperty should return true");
+ ok(!shouldThrow, "Reflect.defineProperty should not throw");
+ } catch(e) {
+ ok(shouldThrow, `Reflect.defineProperty throws ${e}`);
+ }
+ is(setCallbackCount, (index < minLen) ? 0 : 1, "setCallback count");
+ is(deleteCallbackCount, (oldLen > index) ? 1 : 0, "deleteCallback count");
+ is(b[index], shouldThrow ? oldValue : value, "property value");
+ is(b.length, shouldThrow ? oldLen : Math.max(oldLen, index + 1), "length of observable array");
+ });
+
+ // Test other property
+ [
+ // [property, descriptor, expectedResult]
+ ["prop1", {configurable: false, value: "value1"}, true],
+ ["prop1", {configurable: true, value: "value2"}, false],
+ ["prop2", {enumerable: false, value: 5}, true],
+ ["prop3", {enumerable: false, value: []}, true],
+ ["prop4", {enumerable: false, value: {}}, true],
+ ].forEach(function([property, descriptor, expectedResult]) {
+ // Initialize
+ let oldValue = b[property];
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`defining ${property} property with ${JSON.stringify(descriptor)}`);
+ try {
+ is(Reflect.defineProperty(b, property, descriptor), expectedResult,
+ `Reflect.defineProperty should return ${expectedResult}`);
+ ok(true, "Reflect.defineProperty should not throw");
+ } catch(e) {
+ ok(false, `Reflect.defineProperty throws ${e}`);
+ }
+ is(setCallbackCount, 0, "setCallback count");
+ is(deleteCallbackCount, 0, "deleteCallback count");
+ is(b[property], expectedResult ? descriptor.value : oldValue, "property value");
+ is(b.length, oldLen, "length of observable array");
+ });
+});
+
+add_task(function testObservableArrayExoticObjects_deleteProperty() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+ let deleteCallbackTests = null;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (typeof deleteCallbackTests === 'function') {
+ deleteCallbackTests(value, index);
+ }
+ },
+ });
+ m.observableArrayBoolean = [true, true];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 2, "length of observable array should be 2");
+
+ // Test length
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ info("deleting length property");
+ ok(!Reflect.deleteProperty(b, "length"), "test result of deleting length property");
+ is(setCallbackCount, 0, "setCallback should not be called");
+ is(deleteCallbackCount, 0, "deleteCallback should not be called");
+ is(b.length, 2, "length should still be 2");
+
+ // Test indexed value
+ [
+ // [index, expectedResult]
+ [2, false],
+ [0, false],
+ [1, true],
+ ].forEach(function([index, expectedResult]) {
+ // Initialize
+ let oldLen = b.length;
+ let oldValue = b[index];
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ deleteCallbackTests = function(_value, _index) {
+ is(_value, oldValue, "deleteCallbackTests: test value argument");
+ is(_index, index, "deleteCallbackTests: test index argument");
+ };
+
+ // Test
+ info(`deleting ${index} property`);
+ is(Reflect.deleteProperty(b, index), expectedResult,
+ `Reflect.deleteProperty should return ${expectedResult}`);
+ is(setCallbackCount, 0, "setCallback count");
+ is(deleteCallbackCount, expectedResult ? 1 : 0, "deleteCallback count");
+ is(b[index], expectedResult ? undefined : oldValue, "property value");
+ is(b.length, expectedResult ? oldLen - 1 : oldLen,
+ "length of observable array");
+ });
+
+ // Test other property
+ [
+ // [property, value]
+ ["prop1", "value1"],
+ ["prop2", 5],
+ ["prop3", []],
+ ["prop4", {}],
+ ].forEach(function([property, value]) {
+ // Initialize
+ b[property] = value;
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ deleteCallbackTests = null;
+
+ // Test
+ info(`deleting ${property} property`);
+ is(b[property], value, `property value should be ${value} before deleting`);
+ ok(Reflect.deleteProperty(b, property), "Reflect.deleteProperty should return true");
+ is(setCallbackCount, 0, "setCallback count");
+ is(deleteCallbackCount, 0, "deleteCallback count");
+ is(b[property], undefined, "property value should be undefined after deleting");
+ is(b.length, oldLen, "length of observable array");
+ });
+});
+
+add_task(function testObservableArrayExoticObjects_deleteProperty_callback_throw() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (value) {
+ throw new Error("deleteBooleanCallback");
+ }
+ },
+ });
+ m.observableArrayBoolean = [true, false];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 2, "length of observable array should be 2");
+
+ // Test indexed value
+ let index = b.length;
+ while (index--) {
+ // Initialize
+ let oldValue = b[index];
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`deleting index ${index}`);
+ try {
+ ok(Reflect.deleteProperty(b, index), "Reflect.deleteProperty should return true");
+ ok(!oldValue, "Reflect.deleteProperty should not throw");
+ } catch(e) {
+ ok(oldValue, `Reflect.deleteProperty throws ${e}`);
+ }
+ is(setCallbackCount, 0, "setCallback count");
+ is(deleteCallbackCount, 1, "deleteCallback count");
+ is(b[index], oldValue ? oldValue : undefined, "property value");
+ is(b.length, oldValue ? oldLen : oldLen - 1, "length of observable array");
+ }
+
+ // Test other property
+ [
+ // [property, value]
+ ["prop1", "value1"],
+ ["prop2", 5],
+ ["prop3", []],
+ ["prop4", {}],
+ ["prop5", false],
+ ].forEach(function([property, value]) {
+ // Initialize
+ b[property] = value;
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`deleting ${property} property`);
+ is(b[property], value, `property value should be ${JSON.stringify(value)} before deleting`);
+ try {
+ ok(Reflect.deleteProperty(b, property), `Reflect.deleteProperty should return true`);
+ ok(true, "Reflect.deleteProperty should not throw");
+ } catch(e) {
+ ok(false, `Reflect.deleteProperty throws ${e}`);
+ }
+ is(setCallbackCount, 0, "setCallback count");
+ is(deleteCallbackCount, 0, "deleteCallback count");
+ is(b[property], undefined, `property value should be undefined after deleting`);
+ is(b.length, oldLen, "length of observable array");
+ });
+});
+
+add_task(function testObservableArrayExoticObjects_get() {
+ let m = new TestInterfaceObservableArray();
+ m.observableArrayBoolean = [true, false];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 2, "length of observable array should be 2");
+
+ // Test length
+ is(Reflect.get(b, "length"), 2, "test result of getting length property");
+
+ // Test indexed value
+ is(Reflect.get(b, 0), true, "test result of getting index 0");
+ is(Reflect.get(b, 1), false, "test result of getting index 1");
+ is(Reflect.get(b, 2), undefined, "test result of getting index 2");
+
+ // Test other property
+ [
+ // [property, value]
+ ["prop1", "value1"],
+ ["prop2", 5],
+ ["prop3", []],
+ ["prop4", {}],
+ ].forEach(function([property, value]) {
+ is(Reflect.get(b, property), undefined, `test ${property} property before setting property value`);
+ b[property] = value;
+ is(Reflect.get(b, property), value, `test ${property} property after setting property value`);
+ });
+});
+
+add_task(function testObservableArrayExoticObjects_getOwnPropertyDescriptor() {
+ function TestDescriptor(object, property, exist, configurable, enumerable,
+ writable, value) {
+ let descriptor = Reflect.getOwnPropertyDescriptor(object, property);
+ if (!exist) {
+ is(descriptor, undefined, `descriptor of ${property} property should be undefined`);
+ return;
+ }
+
+ is(descriptor.configurable, configurable, `test descriptor of ${property} property (configurable)`);
+ is(descriptor.enumerable, enumerable, `test descriptor of ${property} property (enumerable)`);
+ is(descriptor.writable, writable, `test descriptor of ${property} property (writable)`);
+ is(descriptor.value, value, `test descriptor of ${property} property (value)`);
+ }
+
+ let m = new TestInterfaceObservableArray();
+ m.observableArrayBoolean = [true, false];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 2, "length of observable array should be 2");
+
+ // Test length
+ TestDescriptor(b, "length", true, false /* configurable */,
+ false /* enumerable */, true /* writable */ , 2 /* value */);
+
+ // Test indexed value
+ TestDescriptor(b, 0, true, true /* configurable */, true /* enumerable */,
+ true /* writable */ , true /* value */);
+ TestDescriptor(b, 1, true, true /* configurable */, true /* enumerable */,
+ true /* writable */ , false /* value */);
+ TestDescriptor(b, 2, false);
+
+ // Test other property
+ [
+ // [property, value, configurable, enumerable, writable]
+ ["prop1", "value1", true, true, true],
+ ["prop2", 5, true, true, false],
+ ["prop3", [], true, false, false],
+ ["prop4", {}, false, false, false],
+ ].forEach(function([property, value, configurable, enumerable, writable]) {
+ Object.defineProperty(b, property, {
+ value,
+ configurable,
+ enumerable,
+ writable,
+ });
+ TestDescriptor(b, property, true, configurable, enumerable, writable , value);
+ });
+});
+
+add_task(function testObservableArrayExoticObjects_has() {
+ let m = new TestInterfaceObservableArray();
+ m.observableArrayBoolean = [true, false];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 2, "length of observable array should be 2");
+
+ // Test length
+ ok(Reflect.has(b, "length"), `test length property`);
+
+ // Test indexed value
+ ok(Reflect.has(b, 0), `test 0 property`);
+ ok(Reflect.has(b, 1), `test 1 property`);
+ ok(!Reflect.has(b, 2), `test 2 property`);
+
+ // Test other property
+ [
+ // [property, value]
+ ["prop1", "value1"],
+ ["prop2", 5],
+ ["prop3", []],
+ ["prop4", {}],
+ ].forEach(function([property, value]) {
+ ok(!Reflect.has(b, property), `test ${property} property before setting property value`);
+ b[property] = value;
+ ok(Reflect.has(b, property), `test ${property} property after setting property value`);
+ });
+});
+
+add_task(function testObservableArrayExoticObjects_ownKeys() {
+ let m = new TestInterfaceObservableArray();
+ m.observableArrayBoolean = [true, false];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 2, "length of observable array should be 2");
+
+ // Add other properties
+ b.prop1 = "value1";
+ b.prop2 = 5;
+ b.prop3 = [];
+ b.prop4 = {};
+
+ let keys = Reflect.ownKeys(b);
+ SimpleTest.isDeeply(keys, ["0", "1", "length", "prop1", "prop2", "prop3", "prop4"], `test property keys`);
+});
+
+add_task(function testObservableArrayExoticObjects_preventExtensions() {
+ let m = new TestInterfaceObservableArray();
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 0, "length of observable array should be 0");
+
+ // Test preventExtensions
+ ok(Reflect.isExtensible(b), "test isExtensible before preventExtensions");
+ ok(!Reflect.preventExtensions(b), "test preventExtensions");
+ ok(Reflect.isExtensible(b), "test isExtensible after preventExtensions");
+});
+
+add_task(function testObservableArrayExoticObjects_set() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+ let setCallbackTests = null;
+ let deleteCallbackTests = null;
+
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ if (typeof setCallbackTests === 'function') {
+ setCallbackTests(value, index);
+ }
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (typeof deleteCallbackTests === 'function') {
+ deleteCallbackTests(value, index);
+ }
+ },
+ });
+ m.observableArrayBoolean = [true, true, true];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 3, "length of observable array should be 3");
+
+ // Test length
+ [
+ // [length, shouldThrow, expectedResult]
+ // Invalid length value
+ [1.9, true],
+ ['invalid', true],
+ [{}, true],
+ // length value should not greater than current length
+ [b.length + 1, false, false],
+ // Success
+ [b.length, false, true],
+ [b.length - 1, false, true],
+ [0, false, true],
+ ].forEach(function([length, shouldThrow, expectedResult]) {
+ // Initialize
+ let oldLen = b.length;
+ let oldValues = b.slice();
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ setCallbackTests = null;
+ let deleteCallbackIndex = oldLen - 1;
+ deleteCallbackTests = function(_value, _index) {
+ is(_value, oldValues[deleteCallbackIndex], "deleteCallbackTests: test value argument");
+ is(_index, deleteCallbackIndex, "deleteCallbackTests: test index argument");
+ deleteCallbackIndex--;
+ };
+
+ // Test
+ info(`setting "length" property value to ${length}`);
+ try {
+ is(Reflect.set(b, "length", length), expectedResult, `Reflect.set should return ${expectedResult}`);
+ ok(!shouldThrow, "Reflect.set should not throw");
+ } catch(e) {
+ ok(shouldThrow, `Reflect.set throws ${e}`);
+ }
+ is(setCallbackCount, 0, "setCallback count");
+ is(deleteCallbackCount, expectedResult ? oldLen - length : 0, "deleteCallback count");
+ isDeeply(b, expectedResult ? oldValues.slice(0, length) : oldValues, "property values");
+ is(b.length, expectedResult ? length : oldLen, "length of observable array");
+ });
+
+ // Test indexed value
+ [
+ // [index, value, shouldThrow, expectedResult]
+ // Index could not greater than last index.
+ [b.length + 1, true, false, false],
+ // Success
+ [b.length, true, false, true],
+ [b.length + 1, true, false, true],
+ ].forEach(function([index, value, shouldThrow, expectedResult]) {
+ // Initialize
+ let oldLen = b.length;
+ let oldValue = b[index];
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ setCallbackTests = function(_value, _index) {
+ is(_value, value, "setCallbackTests: test value argument");
+ is(_index, index, "setCallbackTests: test index argument");
+ };
+ deleteCallbackTests = function(_value, _index) {
+ is(_value, oldValue, "deleteCallbackTests: test value argument");
+ is(_index, index, "deleteCallbackTests: test index argument");
+ };
+
+ // Test
+ info(`setting ${index} property to ${value}`);
+ try {
+ is(Reflect.set(b, index, value), expectedResult, `Reflect.set should return ${expectedResult}`);
+ ok(!shouldThrow, "Reflect.set should not throw");
+ } catch(e) {
+ ok(shouldThrow, `Reflect.set throws ${e}`);
+ }
+ is(setCallbackCount, expectedResult ? 1 : 0, "setCallback count");
+ is(deleteCallbackCount, (oldLen > index) ? 1 : 0, "deleteCallback count");
+ is(b[index], expectedResult ? value : oldValue, "property value");
+ is(b.length, expectedResult ? Math.max(index + 1, oldLen) : oldLen, "length of observable array");
+ });
+
+ // Test other property
+ [
+ // [property, value]
+ ["prop1", "value1"],
+ ["prop1", "value2"],
+ ["prop2", 5],
+ ["prop3", []],
+ ["prop4", {}],
+ ].forEach(function([property, value]) {
+ // Initialize
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+ setCallbackTests = null;
+ deleteCallbackTests = null;
+
+ // Test
+ info(`setting ${property} property to ${value}`);
+ ok(Reflect.set(b, property, value), "Reflect.defineProperty should return true");
+ is(setCallbackCount, 0, "setCallback count");
+ is(deleteCallbackCount, 0, "deleteCallback count");
+ is(b[property], value, "property value");
+ is(b.length, oldLen, "length of observable array");
+ });
+});
+
+add_task(function testObservableArrayExoticObjects_set_callback_throw() {
+ let setCallbackCount = 0;
+ let deleteCallbackCount = 0;
+
+ const minLen = 3;
+ let m = new TestInterfaceObservableArray({
+ setBooleanCallback(value, index) {
+ setCallbackCount++;
+ if (value) {
+ throw new Error("setBooleanCallback");
+ }
+ },
+ deleteBooleanCallback(value, index) {
+ deleteCallbackCount++;
+ if (index < minLen) {
+ throw new Error("deleteBooleanCallback");
+ }
+ },
+ });
+ m.observableArrayBoolean = [false, false, false, false, false];
+
+ let b = m.observableArrayBoolean;
+ ok(Array.isArray(b), "observable array should be an array type");
+ is(b.length, 5, "length of observable array should be 3");
+
+ // Test length
+ [
+ // [value, shouldThrow]
+ [b.length, false],
+ [b.length - 1, false],
+ [0, true],
+ ].forEach(function([length, shouldThrow]) {
+ // Initialize
+ let oldValues = b.slice();
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`setting "length" property to ${length}`);
+ try {
+ ok(Reflect.set(b, "length", length), "Reflect.set should return true");
+ ok(!shouldThrow, `Reflect.set should not throw`);
+ } catch(e) {
+ ok(shouldThrow, `Reflect.set throws ${e}`);
+ }
+ is(setCallbackCount, 0, "setCallback should not be called");
+ is(deleteCallbackCount, oldLen - (shouldThrow ? minLen - 1 : length), "deleteCallback count");
+ isDeeply(b, oldValues.slice(0, shouldThrow ? minLen : length), "property values");
+ is(b.length, shouldThrow ? minLen : length, "length of observable array");
+ });
+
+ // Test indexed value
+ [
+ // [index, value, shouldThrow]
+ [b.length, true, true],
+ [b.length, false, false],
+ [b.length + 1, false, false],
+ [b.length + 1, true, true],
+ [0, false, true],
+ [0, true, true],
+ ].forEach(function([index, value, shouldThrow]) {
+ // Initialize
+ let oldValue = b[index];
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`setting ${index} property to ${value}`);
+ try {
+ ok(Reflect.set(b, index, value), "Reflect.set should return true");
+ ok(!shouldThrow, `Reflect.set should not throw`);
+ } catch(e) {
+ ok(shouldThrow, `Reflect.set throws ${e}`);
+ }
+ is(setCallbackCount, (index < minLen) ? 0 : 1, "setCallback count");
+ is(deleteCallbackCount, (oldLen > index) ? 1 : 0, "deleteCallback count");
+ is(b[index], shouldThrow ? oldValue : value, "property value");
+ is(b.length, shouldThrow ? oldLen : Math.max(oldLen, index + 1), "length of observable array");
+ });
+
+ // Test other property
+ [
+ ["prop1", "value1"],
+ ["prop1", "value2"],
+ ["prop2", 5],
+ ["prop3", []],
+ ["prop4", {}],
+ ].forEach(function([property, value]) {
+ // Initialize
+ let oldLen = b.length;
+ setCallbackCount = 0;
+ deleteCallbackCount = 0;
+
+ // Test
+ info(`setting ${property} property to ${JSON.stringify(value)}`);
+ try {
+ ok(Reflect.set(b, property, value), "Reflect.set should return true");
+ ok(true, `Reflect.set should not throw`);
+ } catch(e) {
+ ok(false, `Reflect.set throws ${e}`);
+ }
+ is(setCallbackCount, 0, "setCallback should not be called");
+ is(deleteCallbackCount, 0, "deleteCallback should be called");
+ is(b[property], value, "property value");
+ is(b.length, oldLen, "length of observable array");
+ });
+});
+
+add_task(function testObservableArrayExoticObjects_invalidtype() {
+ let m = new TestInterfaceObservableArray();
+ let i = m.observableArrayInterface;
+ ok(Array.isArray(i), "Observable array should be an array type");
+ is(i.length, 0, "length should be 0");
+
+ [true, "invalid"].forEach(function(value) {
+ SimpleTest.doesThrow(() => {
+ let descriptor = {configurable: true, enumerable: true, writable: true, value};
+ Reflect.defineProperty(i, i.length, descriptor);
+ }, `defining ${i.length} property with ${JSON.stringify(value)} should throw`);
+
+ SimpleTest.doesThrow(() => {
+ Reflect.set(i, i.length, value);
+ }, `setting ${i.length} property to ${JSON.stringify(value)} should throw`);
+ });
+
+ is(i.length, 0, "length should still be 0");
+});
+</script>
+</body>
+</html>
diff --git a/dom/bindings/test/test_oom_reporting.html b/dom/bindings/test/test_oom_reporting.html
new file mode 100644
index 0000000000..3a9d734ba6
--- /dev/null
+++ b/dom/bindings/test/test_oom_reporting.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug </title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug **/
+ SimpleTest.waitForExplicitFinish();
+
+ SimpleTest.expectUncaughtException();
+ setTimeout(function() {
+ SpecialPowers.Cu.getJSTestingFunctions().throwOutOfMemory();
+ }, 0);
+
+ addEventListener("error", function(e) {
+ is(e.type, "error", "Should have an error event");
+ is(e.message, "uncaught exception: out of memory",
+ "Should have the right error message");
+ // Make sure we finish async, in case the expectUncaughtException assertion
+ // about having seen the exception runs after our listener
+ SimpleTest.executeSoon(SimpleTest.finish);
+ });
+
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_prefOnConstructor.html b/dom/bindings/test/test_prefOnConstructor.html
new file mode 100644
index 0000000000..0d8213476e
--- /dev/null
+++ b/dom/bindings/test/test_prefOnConstructor.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1604340
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1604340</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+ /* global WrapperCachedNonISupportsTestInterface */
+ SimpleTest.waitForExplicitFinish();
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]}, go);
+
+ async function go() {
+ await SpecialPowers.pushPrefEnv({set: [["dom.webidl.test1", false]]});
+ let result = null;
+ let constructorThrew = false;
+
+ try {
+ result = new WrapperCachedNonISupportsTestInterface();
+ } catch {
+ constructorThrew = true;
+ }
+
+ is(result, null, "The result value should remain null if the constructor threw an exception as intended.");
+ ok(constructorThrew, "The constructor should throw an exception if its pref is not set to true.");
+
+ await SpecialPowers.pushPrefEnv({set: [["dom.webidl.test1", true]]});
+ result = null;
+ constructorThrew = false;
+
+ try {
+ result = new WrapperCachedNonISupportsTestInterface();
+ } catch {
+ constructorThrew = true;
+ }
+
+ isnot(result, null, "Constructor should have executed successfully.");
+ ok(!constructorThrew, "The constructor should not throw an exception if its pref is set.");
+
+ SimpleTest.finish();
+ }
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1604340">Mozilla Bug 1604340</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_primitive_this.html b/dom/bindings/test/test_primitive_this.html
new file mode 100644
index 0000000000..086ce0f3f2
--- /dev/null
+++ b/dom/bindings/test/test_primitive_this.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=603201
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 603201</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 603201 **/
+
+ SimpleTest.waitForExplicitFinish();
+ function runTest() {
+ var nodes = document.body.childNodes;
+
+ Object.setPrototypeOf(Number.prototype, nodes);
+
+ Object.defineProperty(nodes, "getter", {get() {
+ "use strict";
+ is(this, 1);
+ return "getter";
+ }});
+ Object.defineProperty(Object.getPrototypeOf(nodes), "getter2", {get() {
+ "use strict";
+ is(this, 1);
+ return "getter2";
+ }});
+
+ var number = 1;
+ is(number.getter, "getter");
+ is(number.getter2, "getter2");
+
+ SimpleTest.finish();
+ }
+
+ </script>
+</head>
+<body onload="runTest();">
+<pre>Test</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_promise_rejections_from_jsimplemented.html b/dom/bindings/test/test_promise_rejections_from_jsimplemented.html
new file mode 100644
index 0000000000..ab7e15dc57
--- /dev/null
+++ b/dom/bindings/test/test_promise_rejections_from_jsimplemented.html
@@ -0,0 +1,143 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1107592
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1107592</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+ /* global TestInterfaceJS, thereIsNoSuchContentFunction1, thereIsNoSuchContentFunction2, thereIsNoSuchContentFunction3 */
+ /** Test for Bug 1107592 **/
+
+ SimpleTest.waitForExplicitFinish();
+
+ function checkExn(lineNumber, name, message, code, filename, testNumber, stack, exn) {
+ is(exn.lineNumber, lineNumber,
+ "Should have the right line number in test " + testNumber);
+ is(exn.name, name,
+ "Should have the right exception name in test " + testNumber);
+ is("filename" in exn ? exn.filename : exn.fileName, filename,
+ "Should have the right file name in test " + testNumber);
+ is(exn.message, message,
+ "Should have the right message in test " + testNumber);
+ is(exn.code, code, "Should have the right .code in test " + testNumber);
+ if (message === "") {
+ is(exn.name, "InternalError",
+ "Should have one of our synthetic exceptions in test " + testNumber);
+ }
+ is(exn.stack, stack, "Should have the right stack in test " + testNumber);
+ }
+
+ function ensurePromiseFail(testNumber, value) {
+ ok(false, "Test " + testNumber + " should not have a fulfilled promise");
+ }
+
+ function doTest() {
+ var t = new TestInterfaceJS();
+
+
+ var asyncStack = !SpecialPowers.getBoolPref("javascript.options.asyncstack_capture_debuggee_only");
+ var ourFile = location.href;
+ var unwrapError = "Promise rejection value is a non-unwrappable cross-compartment wrapper.";
+ var parentFrame = asyncStack ? `Async*@${ourFile}:130:17
+` : "";
+
+ Promise.all([
+ t.testPromiseWithThrowingChromePromiseInit().then(
+ ensurePromiseFail.bind(null, 1),
+ checkExn.bind(null, 49, "InternalError", unwrapError,
+ undefined, ourFile, 1,
+ `doTest@${ourFile}:49:9
+` +
+ parentFrame)),
+ t.testPromiseWithThrowingContentPromiseInit(function() {
+ thereIsNoSuchContentFunction1();
+ }).then(
+ ensurePromiseFail.bind(null, 2),
+ checkExn.bind(null, 57, "ReferenceError",
+ "thereIsNoSuchContentFunction1 is not defined",
+ undefined, ourFile, 2,
+ `doTest/<@${ourFile}:57:11
+doTest@${ourFile}:56:9
+` +
+ parentFrame)),
+ t.testPromiseWithThrowingChromeThenFunction().then(
+ ensurePromiseFail.bind(null, 3),
+ checkExn.bind(null, 0, "InternalError", unwrapError, undefined, "", 3, asyncStack ? (`Async*doTest@${ourFile}:67:9
+` +
+ parentFrame) : "")),
+ t.testPromiseWithThrowingContentThenFunction(function() {
+ thereIsNoSuchContentFunction2();
+ }).then(
+ ensurePromiseFail.bind(null, 4),
+ checkExn.bind(null, 73, "ReferenceError",
+ "thereIsNoSuchContentFunction2 is not defined",
+ undefined, ourFile, 4,
+ `doTest/<@${ourFile}:73:11
+` +
+ (asyncStack ? `Async*doTest@${ourFile}:72:9
+` : "") +
+ parentFrame)),
+ t.testPromiseWithThrowingChromeThenable().then(
+ ensurePromiseFail.bind(null, 5),
+ checkExn.bind(null, 0, "InternalError", unwrapError, undefined, "", 5, asyncStack ? (`Async*doTest@${ourFile}:84:9
+` +
+ parentFrame) : "")),
+ t.testPromiseWithThrowingContentThenable({
+ then() { thereIsNoSuchContentFunction3(); },
+ }).then(
+ ensurePromiseFail.bind(null, 6),
+ checkExn.bind(null, 90, "ReferenceError",
+ "thereIsNoSuchContentFunction3 is not defined",
+ undefined, ourFile, 6,
+ `then@${ourFile}:90:22
+` + (asyncStack ? `Async*doTest@${ourFile}:89:9\n` + parentFrame : ""))),
+ t.testPromiseWithDOMExceptionThrowingPromiseInit().then(
+ ensurePromiseFail.bind(null, 7),
+ checkExn.bind(null, 98, "NotFoundError",
+ "We are a second DOMException",
+ DOMException.NOT_FOUND_ERR, ourFile, 7,
+ `doTest@${ourFile}:98:9
+` +
+ parentFrame)),
+ t.testPromiseWithDOMExceptionThrowingThenFunction().then(
+ ensurePromiseFail.bind(null, 8),
+ checkExn.bind(null, asyncStack ? 106 : 0, "NetworkError",
+ "We are a third DOMException",
+ DOMException.NETWORK_ERR, asyncStack ? ourFile : "", 8,
+ (asyncStack ? `Async*doTest@${ourFile}:106:9
+` +
+ parentFrame : ""))),
+ t.testPromiseWithDOMExceptionThrowingThenable().then(
+ ensurePromiseFail.bind(null, 9),
+ checkExn.bind(null, asyncStack ? 114 : 0, "TypeMismatchError",
+ "We are a fourth DOMException",
+ DOMException.TYPE_MISMATCH_ERR,
+ asyncStack ? ourFile : "", 9,
+ (asyncStack ? `Async*doTest@${ourFile}:114:9
+` +
+ parentFrame : ""))),
+ ]).then(SimpleTest.finish,
+ function(err) {
+ ok(false, "One of our catch statements totally failed with err" + err + ", stack: " + (err ? err.stack : ""));
+ SimpleTest.finish();
+ });
+ }
+
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]},
+ doTest);
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1107592">Mozilla Bug 1107592</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_proxies_via_xray.html b/dom/bindings/test/test_proxies_via_xray.html
new file mode 100644
index 0000000000..d7d5dc2d1e
--- /dev/null
+++ b/dom/bindings/test/test_proxies_via_xray.html
@@ -0,0 +1,98 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1021066
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1021066</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1021066">Mozilla Bug 1021066</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<iframe id="t" src="http://example.org/tests/dom/bindings/test/file_proxies_via_xray.html"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 1021066 **/
+
+function test() {
+ "use strict"; // So we'll get exceptions on sets
+ var doc = document.getElementById("t").contentWindow.document;
+ ok(!("x" in doc), "Should have an Xray here");
+ is(doc.x, undefined, "Really should have an Xray here");
+ is(doc.wrappedJSObject.x, 5, "And wrapping the right thing");
+
+ // Test overridebuiltins binding without named setter
+ is(doc.y, doc.getElementById("y"),
+ "Named getter should work on Document");
+ try {
+ doc.z = 5;
+ ok(false, "Should have thrown on set of readonly property on Document");
+ } catch (e) {
+ ok(/read-only/.test(e.message),
+ "Threw the right exception on set of readonly property on Document");
+ }
+
+ doc.w = 5;
+ is(doc.w, 5, "Should be able to set things that are not named props");
+
+ // Test non-overridebuiltins binding without named setter
+ var l = doc.getElementsByTagName("img");
+ is(l.y, doc.getElementById("y"),
+ "Named getter should work on HTMLCollection");
+ try {
+ l.z = 5;
+ ok(false, "Should have thrown on set of readonly property on HTMLCollection");
+ } catch (e) {
+ ok(/read-only/.test(e.message),
+ "Should throw the right exception on set of readonly property on HTMLCollection");
+ }
+ try {
+ l[10] = 5;
+ ok(false, "Should have thrown on set of indexed property on HTMLCollection");
+ } catch (e) {
+ ok(/doesn't have an indexed property setter/.test(e.message),
+ "Should throw the right exception on set of indexed property on HTMLCollection");
+ }
+
+ // Test overridebuiltins binding with named setter
+ var d = doc.documentElement.dataset;
+ d.foo = "bar";
+ // Check that this actually got passed on to the underlying object.
+ is(d.wrappedJSObject.foo, "bar",
+ "Set should get forwarded to the underlying object");
+ is(doc.documentElement.getAttribute("data-foo"), "bar",
+ "Attribute setter should have been called");
+ d.foo = "baz";
+ // Check that this actually got passed on to the underlying object.
+ is(d.wrappedJSObject.foo, "baz",
+ "Set should get forwarded to the underlying object again");
+ is(doc.documentElement.getAttribute("data-foo"), "baz",
+ "Attribute setter should have been called again");
+
+ // Test non-overridebuiltins binding with named setter
+ var s = doc.defaultView.localStorage;
+ s.test_proxies_via_xray = "bar";
+ // Check that this actually got passed on to the underlying object.
+ is(s.wrappedJSObject.test_proxies_via_xray, "bar",
+ "Set should get forwarded to the underlying object without overridebuiltins");
+ s.test_proxies_via_xray = "baz";
+ // Check that this actually got passed on to the underlying object.
+ is(s.wrappedJSObject.test_proxies_via_xray, "baz",
+ "Set should get forwarded to the underlying object again without overridebuiltins");
+
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(test);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_proxy_accessors.html b/dom/bindings/test/test_proxy_accessors.html
new file mode 100644
index 0000000000..9474369688
--- /dev/null
+++ b/dom/bindings/test/test_proxy_accessors.html
@@ -0,0 +1,78 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1700052
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1700052</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=1700052">Mozilla Bug 1700052</a>
+<p id="display"></p>
+<form id="theform"></form>
+<pre id="test">
+<script>
+function expandoTests() {
+ // Get a DOM proxy with an expando object. Define/redefine a "foo" getter/setter
+ // and ensure the right function is called.
+
+ var obj = document.getElementById("theform");
+ var count1 = 0, count2 = 0, count3 = 0;
+ var fun1 = function() { count1++; };
+ var fun2 = function() { count2++; };
+ var fun3 = function() { count3++; };
+
+ Object.defineProperty(obj, "foo", {configurable: true, get: fun1, set: fun1});
+
+ for (var i = 0; i < 100; i++) {
+ obj.foo;
+ obj.foo = i;
+ if (i === 50) {
+ Object.defineProperty(obj, "foo", {configurable: true, get: fun2, set: fun2});
+ } else if (i === 80) {
+ Object.defineProperty(obj, "foo", {configurable: true, get: fun3, set: fun3});
+ }
+ }
+
+ is(count1, 102, "call count for fun1 must match");
+ is(count2, 60, "call count for fun2 must match");
+ is(count3, 38, "call count for fun3 must match");
+}
+expandoTests();
+
+function unshadowedTests() {
+ // Same as above, but for non-shadowing properties on the prototype.
+
+ var obj = document.getElementById("theform");
+ var proto = Object.getPrototypeOf(obj);
+
+ var count1 = 0, count2 = 0;
+ var fun1 = function() { count1++; };
+ var fun2 = function() { count2++; };
+
+ for (var i = 0; i < 100; i++) {
+ obj.name;
+ obj.name = "test";
+ if (i === 50) {
+ let desc = Object.getOwnPropertyDescriptor(proto, "name");
+ desc.get = desc.set = fun1;
+ Object.defineProperty(proto, "name", desc);
+ }
+ if (i === 90) {
+ let desc = Object.getOwnPropertyDescriptor(proto, "name");
+ desc.get = desc.set = fun2;
+ Object.defineProperty(proto, "name", desc);
+ }
+ }
+
+ is(count1, 80, "call count for fun1 must match");
+ is(count2, 18, "call count for fun2 must match");
+}
+unshadowedTests();
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_proxy_expandos.html b/dom/bindings/test/test_proxy_expandos.html
new file mode 100644
index 0000000000..bfe6ab598c
--- /dev/null
+++ b/dom/bindings/test/test_proxy_expandos.html
@@ -0,0 +1,86 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=965992
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 965992</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=965992">Mozilla Bug 965992</a>
+<p id="display"></p>
+<form id="theform"></form>
+<pre id="test">
+<script type="application/javascript">
+
+// Ensure we are in JIT code and attach IC stubs.
+const iterations = 50;
+
+function testFoo(obj, kind, expected) {
+ for (var i = 0; i < iterations; i++) {
+ obj.foo = i;
+ is(obj.foo, (expected === undefined) ? i : expected,
+ "Looking up an expando should work - " + kind);
+ }
+}
+
+function getPropTests(obj) {
+ // Start with a plain data property.
+ obj.foo = "bar";
+ testFoo(obj, "plain");
+
+ // Now change it to a scripted getter/setter.
+ var count = 0;
+ var getterSetterVal = 0;
+ Object.defineProperty(obj, "foo", {configurable: true, get() {
+ is(this, obj, "Getter should have the proxy as |this|");
+ is(arguments.length, 0, "Shouldn't pass arguments to getters");
+ count++;
+ return getterSetterVal;
+ }, set(v) {
+ is(this, obj, "Setter should have the proxy as |this|");
+ is(arguments.length, 1, "Should pass 1 argument to setters");
+ getterSetterVal = v;
+ count++;
+ }});
+ testFoo(obj, "scripted getter/setter");
+ is(count, iterations * 2, "Should have called the getter/setter enough times");
+
+ // Now try a native getter/setter.
+ Object.defineProperty(obj, "foo", {get: Math.abs, set: Math.abs, configurable: true});
+ testFoo(obj, "native getter/setter", NaN);
+}
+
+function getElemTests(obj) {
+ // Define two expando properties, then test inline caches for obj[prop]
+ // correctly guard on prop being the same.
+ var count = 0, getterSetterVal = 0;
+ obj.elem1 = 1;
+ Object.defineProperty(obj, "elem2", {
+ get() { count++; return getterSetterVal; },
+ set(v) { getterSetterVal = v; count++; },
+ });
+ for (var i = 0; i < iterations; i++) {
+ var prop = ((i & 1) == 0) ? "elem1" : "elem2";
+ obj[prop] = i;
+ is(obj[prop], i, "Should return correct property value");
+ }
+ is(count, iterations, "Should have called the getter/setter enough times");
+}
+
+var directExpando = document.getElementsByTagName("*");
+var indirectExpando = document.getElementById("theform");
+
+getPropTests(directExpando);
+getPropTests(indirectExpando);
+
+getElemTests(indirectExpando);
+getElemTests(directExpando);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_proxy_missing_prop.html b/dom/bindings/test/test_proxy_missing_prop.html
new file mode 100644
index 0000000000..cdb6851722
--- /dev/null
+++ b/dom/bindings/test/test_proxy_missing_prop.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1863543
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1863543</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=1863543">Mozilla Bug 1863543</a>
+<p id="display"></p>
+<pre id="test">
+<script>
+// Test for JIT IC guards for missing properties on the HTMLDocument DOM proxy.
+function testMissingProps() {
+ var doc = document;
+ var docProto = Object.getPrototypeOf(doc);
+
+ for (var i = 0; i < 30; i++) {
+ if (i === 15) {
+ // Add shadowing expando property.
+ doc.unusedPropName1 = 12;
+ }
+ if (i === 20) {
+ // Add prototype property.
+ docProto.unusedPropName2 = 34;
+ }
+ if (i == 25) {
+ // Add shadowing element.
+ var el = document.createElement("object");
+ el.id = "unusedPropName3";
+ document.body.appendChild(el);
+ }
+ var v1 = doc.unusedPropName1;
+ var v2 = doc.unusedPropName2;
+ var v3 = doc.unusedPropName3;
+ is(v1, i >= 15 ? 12 : undefined);
+ is(v2, i >= 20 ? 34 : undefined);
+ is(v3, i >= 25 ? el : undefined);
+ }
+}
+testMissingProps();
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_remoteProxyAsPrototype.html b/dom/bindings/test/test_remoteProxyAsPrototype.html
new file mode 100644
index 0000000000..23846cf85b
--- /dev/null
+++ b/dom/bindings/test/test_remoteProxyAsPrototype.html
@@ -0,0 +1,37 @@
+<!-- Any copyright is dedicated to the Public Domain.
+- http://creativecommons.org/publicdomain/zero/1.0/ -->
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>Test for bug 1773732</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<script>
+
+SimpleTest.waitForExplicitFinish();
+
+function go() {
+ let frame = document.createElement("iframe");
+ frame.onload = () => {
+ let win = frame.contentWindow;
+
+ // The processes will be remote only with isolateEverything strategy
+ const expected = SpecialPowers.effectiveIsolationStrategy() == SpecialPowers.ISOLATION_STRATEGY.IsolateEverything;
+
+ is(SpecialPowers.Cu.isRemoteProxy(win), expected,
+ "win is a remote proxy if Fission is enabled and strategy is isolateEverything");
+ let o = {};
+ Object.setPrototypeOf(o, win);
+ is(Object.getPrototypeOf(o), win, "should have expected proto");
+ SimpleTest.finish();
+ };
+ frame.src = "https://example.com";
+ document.body.appendChild(frame);
+};
+go();
+
+</script>
+</body>
+</html>
diff --git a/dom/bindings/test/test_resizable_arraybufferview.html b/dom/bindings/test/test_resizable_arraybufferview.html
new file mode 100644
index 0000000000..f57ada5b68
--- /dev/null
+++ b/dom/bindings/test/test_resizable_arraybufferview.html
@@ -0,0 +1,97 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1842773
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for resizable ArrayBufferViews</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=1842773">Mozilla Bug 1842773</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+ <script type="application/javascript">
+ /* global TestFunctions */
+
+ SimpleTest.waitForExplicitFinish();
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]}, go);
+
+ function checkThrowsResizable(f) {
+ let ex;
+ try{
+ f();
+ ok(false, "Should have thrown!");
+ } catch (e) {
+ ex = e;
+ }
+ ok(ex.toString().includes("resizable ArrayBuffer or ArrayBufferView"), "Got exception: " + ex);
+ }
+
+ function go() {
+ let test = new TestFunctions();
+
+ let ab = new ArrayBuffer(16, {maxByteLength: 16});
+ checkThrowsResizable(() => test.testNotAllowShared(ab));
+ checkThrowsResizable(() => test.testAllowShared(ab));
+ checkThrowsResizable(() => test.testDictWithAllowShared({arrayBuffer: ab}));
+ checkThrowsResizable(() => test.testUnionOfBuffferSource(ab));
+ checkThrowsResizable(() => { test.arrayBuffer = ab; });
+ checkThrowsResizable(() => { test.allowSharedArrayBuffer = ab; });
+ checkThrowsResizable(() => { test.sequenceOfArrayBuffer = [ab]; });
+ checkThrowsResizable(() => { test.sequenceOfAllowSharedArrayBuffer = [ab]; });
+
+ let ta = new Int8Array(ab);
+ checkThrowsResizable(() => test.testNotAllowShared(ta));
+ checkThrowsResizable(() => test.testAllowShared(ta));
+ checkThrowsResizable(() => test.testDictWithAllowShared({arrayBufferView: ta}));
+ checkThrowsResizable(() => test.testUnionOfBuffferSource(ta));
+ checkThrowsResizable(() => { test.arrayBufferView = ta; });
+ checkThrowsResizable(() => { test.allowSharedArrayBufferView = ta; });
+ checkThrowsResizable(() => { test.sequenceOfArrayBufferView = [ta]; });
+ checkThrowsResizable(() => { test.sequenceOfAllowSharedArrayBufferView = [ta]; });
+
+ let dv = new DataView(ab);
+ checkThrowsResizable(() => test.testNotAllowShared(dv));
+ checkThrowsResizable(() => test.testAllowShared(dv));
+ checkThrowsResizable(() => test.testDictWithAllowShared({arrayBufferView: dv}));
+ checkThrowsResizable(() => test.testUnionOfBuffferSource(dv));
+ checkThrowsResizable(() => { test.arrayBufferView = dv; });
+ checkThrowsResizable(() => { test.allowSharedArrayBufferView = dv; });
+ checkThrowsResizable(() => { test.sequenceOfArrayBufferView = [dv]; });
+ checkThrowsResizable(() => { test.sequenceOfAllowSharedArrayBufferView = [dv]; });
+
+ if (this.SharedArrayBuffer) {
+ let sab = new SharedArrayBuffer(16, {maxByteLength: 16});
+ checkThrowsResizable(() => test.testAllowShared(sab));
+ checkThrowsResizable(() => test.testDictWithAllowShared({allowSharedArrayBuffer: sab}));
+ checkThrowsResizable(() => test.testUnionOfAllowSharedBuffferSource(sab));
+ checkThrowsResizable(() => { test.allowSharedArrayBuffer = sab; });
+ checkThrowsResizable(() => { test.sequenceOfAllowSharedArrayBuffer = [sab]; });
+
+ let sta = new Int8Array(sab);
+ checkThrowsResizable(() => test.testAllowShared(sta));
+ checkThrowsResizable(() => test.testDictWithAllowShared({allowSharedArrayBufferView: sta}));
+ checkThrowsResizable(() => test.testUnionOfAllowSharedBuffferSource(sta));
+ checkThrowsResizable(() => { test.allowSharedArrayBufferView = sta; });
+ checkThrowsResizable(() => { test.sequenceOfAllowSharedArrayBufferView = [sta]; });
+
+ let sdv = new DataView(sab);
+ checkThrowsResizable(() => test.testAllowShared(sdv));
+ checkThrowsResizable(() => test.testDictWithAllowShared({allowSharedArrayBufferView: sdv}));
+ checkThrowsResizable(() => test.testUnionOfAllowSharedBuffferSource(sdv));
+ checkThrowsResizable(() => { test.allowSharedArrayBufferView = sdv; });
+ checkThrowsResizable(() => { test.sequenceOfAllowSharedArrayBufferView = [sdv]; });
+ }
+
+ SimpleTest.finish();
+ }
+ </script>
+</body>
+</html>
diff --git a/dom/bindings/test/test_returnUnion.html b/dom/bindings/test/test_returnUnion.html
new file mode 100644
index 0000000000..eca681068a
--- /dev/null
+++ b/dom/bindings/test/test_returnUnion.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1048659
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1048659</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+ /* global TestInterfaceJS */
+ /** Test for returning unions from JS-implemented WebIDL. **/
+ SimpleTest.waitForExplicitFinish();
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]}, go);
+
+ function go() {
+ var t = new TestInterfaceJS();
+ var t2 = new TestInterfaceJS();
+
+ is(t.pingPongUnion(t2), t2, "ping pong union for left case should be identity");
+ is(t.pingPongUnion(12), 12, "ping pong union for right case should be identity");
+
+ is(t.pingPongUnionContainingNull("this is not a string"), "this is not a string",
+ "ping pong union containing union for left case should be identity");
+ is(t.pingPongUnionContainingNull(null), null,
+ "ping pong union containing null for right case null should be identity");
+ is(t.pingPongUnionContainingNull(t2), t2,
+ "ping pong union containing null for right case should be identity");
+
+ is(t.pingPongNullableUnion(t2), t2, "ping pong nullable union for left case should be identity");
+ is(t.pingPongNullableUnion(12), 12, "ping pong nullable union for right case should be identity");
+ is(t.pingPongNullableUnion(null), null, "ping pong nullable union for null case should be identity");
+
+ var rejectedBadUnion = false;
+ var result = null;
+ try {
+ result = t.returnBadUnion();
+ } catch (e) {
+ rejectedBadUnion = true;
+ }
+ is(result, null, "bad union should not set a value for result");
+ ok(rejectedBadUnion, "bad union should throw an exception");
+
+ SimpleTest.finish();
+ }
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1048659">Mozilla Bug 1048659</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_sequence_detection.html b/dom/bindings/test/test_sequence_detection.html
new file mode 100644
index 0000000000..714d9a5cb1
--- /dev/null
+++ b/dom/bindings/test/test_sequence_detection.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1066432
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1066432</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+ /* global TestInterfaceJS */
+ /** Test for Bug 1066432 **/
+ SimpleTest.waitForExplicitFinish();
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]}, function() {
+ var testInterfaceJS = new TestInterfaceJS();
+ ok(testInterfaceJS, "got a TestInterfaceJS object");
+
+ var nonIterableObject = {[Symbol.iterator]: 5};
+
+ try {
+ testInterfaceJS.testSequenceOverload(nonIterableObject);
+ ok(false, "Should have thrown in the overload case"); // see long comment above!
+ } catch (e) {
+ is(e.name, "TypeError", "Should get a TypeError for the overload case");
+ ok(e.message.includes("not iterable"),
+ "Should have a message about being non-iterable in the overload case");
+ }
+
+ try {
+ testInterfaceJS.testSequenceUnion(nonIterableObject);
+ ok(false, "Should have thrown in the union case");
+ } catch (e) {
+ is(e.name, "TypeError", "Should get a TypeError for the union case");
+ ok(e.message.includes("not iterable"),
+ "Should have a message about being non-iterable in the union case");
+ }
+
+ SimpleTest.finish();
+ });
+
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1066432">Mozilla Bug 1066432</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_sequence_wrapping.html b/dom/bindings/test/test_sequence_wrapping.html
new file mode 100644
index 0000000000..34d901fb66
--- /dev/null
+++ b/dom/bindings/test/test_sequence_wrapping.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=775852
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 775852</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=775852">Mozilla Bug 775852</a>
+<p id="display"></p>
+<iframe id="content" style="display: none">
+</iframe>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 775852 **/
+function doTest() {
+ let win = document.getElementById("content").contentWindow;
+ let doc = win.document;
+ doc.body.innerHTML = `<canvas width="1" height="1" id="c"></canvas>`;
+
+ let gl = doc.getElementById("c").getContext("experimental-webgl");
+ if (!gl) {
+ // No WebGL support on MacOS 10.5. Just skip this test
+ todo(false, "WebGL not supported");
+ return;
+ }
+ var setterCalled = false;
+
+ var extLength = gl.getSupportedExtensions().length;
+ ok(extLength > 0,
+ "This test won't work right if we have no supported extensions");
+
+ win.Object.defineProperty(win.Array.prototype, "0",
+ {
+ set(val) {
+ setterCalled = true;
+ },
+ });
+
+ // Test that our property got defined correctly
+ let arr = new win.Array();
+ arr[0] = 5;
+ is(setterCalled, true, "Setter should be called when setting prop on array");
+
+ setterCalled = false;
+
+ is(gl.getSupportedExtensions().length, extLength,
+ "We should still have the same number of extensions");
+
+ is(setterCalled, false,
+ "Setter should not be called when getting supported extensions");
+}
+doTest();
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_setWithNamedGetterNoNamedSetter.html b/dom/bindings/test/test_setWithNamedGetterNoNamedSetter.html
new file mode 100644
index 0000000000..ec5b048987
--- /dev/null
+++ b/dom/bindings/test/test_setWithNamedGetterNoNamedSetter.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1043690
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1043690</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=1043690">Mozilla Bug 1043690</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<form>
+ <input name="action">
+</form>
+</div>
+ <script type="application/javascript">
+
+ /** Test for Bug 1043690 **/
+ var f = document.querySelector("form");
+ var i = document.querySelector("input");
+ is(f.getAttribute("action"), null, "Should have no action attribute");
+ is(f.action, i, "form.action should be the input");
+ f.action = "http://example.org";
+ is(f.getAttribute("action"), "http://example.org",
+ "Should have an action attribute now");
+ is(f.action, i, "form.action should still be the input");
+ i.remove();
+ is(f.action, "http://example.org/",
+ "form.action should no longer be shadowed");
+
+
+ </script>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_stringBindings.html b/dom/bindings/test/test_stringBindings.html
new file mode 100644
index 0000000000..ad8b60df07
--- /dev/null
+++ b/dom/bindings/test/test_stringBindings.html
@@ -0,0 +1,109 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1334537
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1334537</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1334537 **/
+ SimpleTest.waitForExplicitFinish();
+
+ function go() {
+ // Need a new global that will pick up our pref.
+ var ifr = document.createElement("iframe");
+ document.body.appendChild(ifr);
+
+ var t = new ifr.contentWindow.TestFunctions();
+ var testString = "abcdefghijklmnopqrstuvwxyz";
+ const substringLength = 10;
+ var shortTestString = testString.substring(0, substringLength);
+
+ t.setStringData(testString);
+ // Note: we want to do all our gets before we start running code we don't
+ // control inside the test harness, if we really want to exercise the string
+ // cache in controlled ways.
+
+ var asShortDOMString = t.getStringDataAsDOMString(substringLength);
+ var asFullDOMString = t.getStringDataAsDOMString();
+ var asShortAString = t.getStringDataAsAString(substringLength);
+ var asAString = t.getStringDataAsAString();
+
+ is(asShortDOMString, shortTestString, "Short DOMString should be short");
+ is(asFullDOMString, testString, "Full DOMString should be test string");
+ is(asShortAString, shortTestString, "Short AString should be short");
+ is(asAString, testString, "Full AString should be test string");
+
+ // These strings should match the strings used in TestFunctions.cpp, but we
+ // want to launder them through something on the JS side that will convert
+ // them into strings stored in the JS heap.
+ function launder(str) {
+ // This should be sufficient, but if the JIT gets too smart we may need
+ // to get more clever.
+ return str.split("").join("");
+ }
+ var shortString = launder(t.getShortLiteralString());
+ var mediumString = launder(t.getMediumLiteralString());
+ var longString = launder(t.getLongLiteralString());
+
+ // A short or medium non-external string will become an inline FakeString.
+ is(t.getStringType(shortString), "inline",
+ "Short string should become inline");
+ is(t.getStringType(mediumString), "inline",
+ "Medium string should become inline");
+ // A long string will become a stringbuffer FakeString on the way in.
+ is(t.getStringType(longString), "stringbuffer",
+ "Long string should become a stringbuffer");
+
+ // A short literal string will become an inline JS string on the way out
+ // and then become an inline FakeString on the way in.
+ is(t.getStringType(t.getShortLiteralString()), "inline",
+ "Short literal string should become inline");
+ // A medium or long literal string will become an external JS string on the
+ // way out and then become a literal FakeString on the way in.
+ is(t.getStringType(t.getMediumLiteralString()), "literal",
+ "Medium literal string should become literal");
+ is(t.getStringType(t.getLongLiteralString()), "literal",
+ "Long literal string should become literal");
+
+ // A short stringbuffer string will become an inline JS string on the way
+ // out and then become an inline FakeString on the way in.
+ is(t.getStringType(t.getStringbufferString(shortString)), "inline",
+ "Short stringbuffer string should become inline");
+ // A medium or long stringbuffer string will become an external JS string
+ // on the way out and then become a stringbuffer FakeString on the way in.
+ is(t.getStringType(t.getStringbufferString(mediumString)), "stringbuffer",
+ "Medium stringbuffer string should become stringbuffer");
+ is(t.getStringType(t.getStringbufferString(longString)), "stringbuffer",
+ "Long stringbuffer string should become stringbuffer");
+
+ // Now test that roundtripping works fine. We need to make sure the string
+ // we are storing is not equal to any of the ones we have used above, to
+ // avoid the external string cache interfering.
+ t.setStringData(longString + "unique"); // Should store with stringbuffer.
+ ok(t.stringbufferMatchesStored(t.getStringDataAsAString()),
+ "Stringbuffer should have roundtripped");
+
+ SimpleTest.finish();
+ }
+
+ addLoadEvent(function() {
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]},
+ go);
+ });
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1334537">Mozilla Bug 1334537</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_throwing_method_noDCE.html b/dom/bindings/test/test_throwing_method_noDCE.html
new file mode 100644
index 0000000000..92d1a0b7f9
--- /dev/null
+++ b/dom/bindings/test/test_throwing_method_noDCE.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Test that we don't DCE functions that can throw</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+/* global test, assert_true */
+test(function() {
+ function test(root) {
+ var threw = false;
+ try {
+ root.querySelectorAll("");
+ } catch (e) { threw = true; }
+ // Hot loop to make sure the JIT heuristics ion-compile this function even
+ // though it's throwing exceptions (which would normally make us back off
+ // of ion compilation).
+ for (var i = 0; i < 1500; i++) {
+ // empty
+ }
+ return threw;
+ }
+
+ var threw = false;
+ var el = document.createElement("div");
+ for (var i = 0; i < 200; i++)
+ threw = test(el);
+ assert_true(threw);
+}, "Shouldn't optimize away throwing functions");
+</script>
diff --git a/dom/bindings/test/test_toJSON.html b/dom/bindings/test/test_toJSON.html
new file mode 100644
index 0000000000..9bd9a5989a
--- /dev/null
+++ b/dom/bindings/test/test_toJSON.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1465602
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1465602</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=1465602">Mozilla Bug 1465602</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+ <iframe></iframe>
+</div>
+<pre id="test">
+</pre>
+ <script type="application/javascript">
+ /* global TestFunctions */
+ /** Test for Bug 1465602 **/
+
+ SimpleTest.waitForExplicitFinish();
+ SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]}, go);
+
+ function go() {
+ var ourObj = new TestFunctions();
+ is(ourObj.one, 1, "Basic sanity check for our 'one'");
+ is(ourObj.two, undefined, "Basic sanity check for our 'two'");
+
+ var otherObj = new frames[0].TestFunctions();
+ is(otherObj.one, 1, "Basic sanity check for subframe 'one'");
+ is(otherObj.two, 2, "Basic sanity check for subframe 'two'");
+
+ var ourToJSON = ourObj.toJSON();
+ is(ourToJSON.one, 1, "We should have correct value for 'one'");
+ is(ourToJSON.two, undefined, "We should have correct value for 'two'");
+ ok(!Object.hasOwnProperty(ourToJSON, "two"),
+ "We should not have a property named 'two'");
+
+ var otherToJSON = otherObj.toJSON();
+ is(otherToJSON.one, 1, "Subframe should have correct value for 'one'");
+ is(otherToJSON.two, 2, "Subframe should have correct value for 'two'");
+
+ var mixedToJSON = ourObj.toJSON.call(otherObj);
+ is(mixedToJSON.one, 1, "First test should have correct value for 'one'");
+ is(mixedToJSON.two, 2, "First test should have correct value for 'two'");
+
+ mixedToJSON = otherObj.toJSON.call(ourObj);
+ is(mixedToJSON.one, 1, "Second test should have correct value for 'one'");
+ is(mixedToJSON.two, undefined,
+ "Second test should have correct value for 'two'");
+
+ SimpleTest.finish();
+ }
+ </script>
+</body>
+</html>
diff --git a/dom/bindings/test/test_traceProtos.html b/dom/bindings/test/test_traceProtos.html
new file mode 100644
index 0000000000..b649b6ec8c
--- /dev/null
+++ b/dom/bindings/test/test_traceProtos.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=744772
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 744772</title>
+ <script src="/tests/SimpleTest/SimpleTest.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=744772">Mozilla Bug 744772</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 744772 **/
+
+SimpleTest.waitForExplicitFinish();
+
+function callback() {
+ new XMLHttpRequest().upload;
+ ok(true, "Accessing unreferenced DOM interface objects shouldn't crash");
+ SimpleTest.finish();
+}
+
+delete window.XMLHttpRequestUpload;
+SpecialPowers.exactGC(callback);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_treat_non_object_as_null.html b/dom/bindings/test/test_treat_non_object_as_null.html
new file mode 100644
index 0000000000..785a2ebc71
--- /dev/null
+++ b/dom/bindings/test/test_treat_non_object_as_null.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=952365
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 952365</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 952365 **/
+
+ var onvolumechange;
+ var x = {};
+
+ (function() {
+ onvolumechange = x;
+ is(onvolumechange, x,
+ "Should preserve an object value when assigning to event handler");
+ // Test that we don't try to actually call the non-callable object
+ window.dispatchEvent(new Event("volumechange"));
+ onvolumechange = 5;
+ is(onvolumechange, null,
+ "Non-object values should become null when assigning to event handler");
+ })();
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=952365">Mozilla Bug 952365</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>
diff --git a/dom/bindings/test/test_unforgeablesonexpando.html b/dom/bindings/test/test_unforgeablesonexpando.html
new file mode 100644
index 0000000000..3db4350c9a
--- /dev/null
+++ b/dom/bindings/test/test_unforgeablesonexpando.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Test for making sure named getters don't override the unforgeable location on HTMLDocument</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<img name="location">
+<script>
+/* global test, assert_equals */
+test(function() {
+ assert_equals(document.location, window.location,
+ 'The <img name="location"> should not override the location getter');
+}, "document.location is the right thing");
+test(function() {
+ var doc = new DOMParser().parseFromString("<img name='location'>", "text/html");
+ assert_equals(doc.location, null,
+ 'The <img name="location"> should not override the location getter on a data document');
+}, "document.location is the right thing on non-rendered document");
+</script>
diff --git a/dom/bindings/test/test_usvstring.html b/dom/bindings/test/test_usvstring.html
new file mode 100644
index 0000000000..bef4d5e1fa
--- /dev/null
+++ b/dom/bindings/test/test_usvstring.html
@@ -0,0 +1,43 @@
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test USVString</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<script class="testbody" type="application/javascript">
+/* global TestInterfaceJS */
+
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv({set: [["dom.expose_test_interfaces", true]]}, function() {
+ var testInterfaceJS = new TestInterfaceJS();
+ ok(testInterfaceJS, "got a TestInterfaceJS object");
+ // For expected values, see algorithm definition here:
+ // http://heycam.github.io/webidl/#dfn-obtain-unicode
+ var testList = [
+ { string: "foo",
+ expected: "foo" },
+ { string: "This is U+2070E: \ud841\udf0e",
+ expected: "This is U+2070E: \ud841\udf0e" },
+ { string: "Missing low surrogate: \ud841",
+ expected: "Missing low surrogate: \ufffd" },
+ { string: "Missing low surrogate with trailer: \ud841!!",
+ expected: "Missing low surrogate with trailer: \ufffd!!" },
+ { string: "Missing high surrogate: \udf0e",
+ expected: "Missing high surrogate: \ufffd" },
+ { string: "Missing high surrogate with trailer: \udf0e!!",
+ expected: "Missing high surrogate with trailer: \ufffd!!" },
+ { string: "U+2070E after malformed: \udf0e\ud841\udf0e",
+ expected: "U+2070E after malformed: \ufffd\ud841\udf0e" },
+ ];
+ testList.forEach(function(test) {
+ is(testInterfaceJS.convertSVS(test.string), test.expected, "Convert '" + test.string + "'");
+ });
+ SimpleTest.finish();
+});
+</script>
+</body>
+</html>
diff --git a/dom/bindings/test/test_worker_UnwrapArg.html b/dom/bindings/test/test_worker_UnwrapArg.html
new file mode 100644
index 0000000000..8bc23fa630
--- /dev/null
+++ b/dom/bindings/test/test_worker_UnwrapArg.html
@@ -0,0 +1,58 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1127206
+-->
+<head>
+ <meta charset="utf-8">
+ <title>Test for Bug 1127206</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+ <script type="application/javascript">
+
+ /** Test for Bug 1127206 **/
+ SimpleTest.waitForExplicitFinish();
+ var blob = new Blob([
+ `try { new File({}); }
+ catch (e) {
+ postMessage("throwing on random object");
+ }
+ try { new File(new Blob(["abc"])); }
+ catch (e) {
+ postMessage("throwing on Blob");
+ }
+ try { new File("abc"); }
+ catch (e) {
+ postMessage("throwing on string");
+ }
+ postMessage('finishTest')`]);
+ var url = URL.createObjectURL(blob);
+ var w = new Worker(url);
+ var expectedResults = [
+ "throwing on random object",
+ "throwing on Blob",
+ "throwing on string",
+ ];
+ var curIndex = 0;
+ w.onmessage = function(e) {
+ if (curIndex == expectedResults.length) {
+ is(e.data, "finishTest", "What message is this?");
+ SimpleTest.finish();
+ } else {
+ is(e.data, expectedResults[curIndex],
+ "Message " + (curIndex + 1) + " should be correct");
+ ++curIndex;
+ }
+ };
+ </script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1127206">Mozilla Bug 1127206</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>