Bug 1936278 - Prevent search mode chiclet from being dismissed when clicking in page...
[gecko.git] / dom / bindings / ToJSValue.cpp
blob9429cf292bf9853673a202d073a917ff1d4460bf
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/ToJSValue.h"
8 #include "mozilla/dom/DOMException.h"
9 #include "mozilla/dom/Exceptions.h"
10 #include "mozilla/dom/Promise.h"
11 #include "mozilla/dom/WindowProxyHolder.h"
12 #include "nsAString.h"
13 #include "nsContentUtils.h"
14 #include "mozilla/StringBuffer.h"
15 #include "xpcpublic.h"
17 namespace mozilla::dom {
19 bool ToJSValue(JSContext* aCx, const nsAString& aArgument,
20 JS::MutableHandle<JS::Value> aValue) {
21 // Make sure we're called in a compartment
22 MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
23 return xpc::NonVoidStringToJsval(aCx, aArgument, aValue);
26 bool ToJSValue(JSContext* aCx, const nsACString& aArgument,
27 JS::MutableHandle<JS::Value> aValue) {
28 return UTF8StringToJsval(aCx, aArgument, aValue);
31 bool ToJSValue(JSContext* aCx, nsresult aArgument,
32 JS::MutableHandle<JS::Value> aValue) {
33 RefPtr<Exception> exception = CreateException(aArgument);
34 return ToJSValue(aCx, exception, aValue);
37 bool ToJSValue(JSContext* aCx, ErrorResult&& aArgument,
38 JS::MutableHandle<JS::Value> aValue) {
39 MOZ_ASSERT(aArgument.Failed());
40 MOZ_ASSERT(
41 !aArgument.IsUncatchableException(),
42 "Doesn't make sense to convert uncatchable exception to a JS value!");
43 MOZ_ALWAYS_TRUE(aArgument.MaybeSetPendingException(aCx));
44 MOZ_ALWAYS_TRUE(JS_GetPendingException(aCx, aValue));
45 JS_ClearPendingException(aCx);
46 return true;
49 bool ToJSValue(JSContext* aCx, Promise& aArgument,
50 JS::MutableHandle<JS::Value> aValue) {
51 aValue.setObject(*aArgument.PromiseObj());
52 return MaybeWrapObjectValue(aCx, aValue);
55 bool ToJSValue(JSContext* aCx, const WindowProxyHolder& aArgument,
56 JS::MutableHandle<JS::Value> aValue) {
57 BrowsingContext* bc = aArgument.get();
58 if (!bc) {
59 aValue.setNull();
60 return true;
62 JS::Rooted<JSObject*> windowProxy(aCx);
63 if (bc->IsInProcess()) {
64 windowProxy = bc->GetWindowProxy();
65 if (!windowProxy) {
66 nsPIDOMWindowOuter* window = bc->GetDOMWindow();
67 if (!window) {
68 // Torn down enough that we should just return null.
69 aValue.setNull();
70 return true;
72 if (!window->EnsureInnerWindow()) {
73 return Throw(aCx, NS_ERROR_UNEXPECTED);
75 windowProxy = bc->GetWindowProxy();
77 return ToJSValue(aCx, windowProxy, aValue);
80 if (!GetRemoteOuterWindowProxy(aCx, bc, /* aTransplantTo = */ nullptr,
81 &windowProxy)) {
82 return false;
84 aValue.setObjectOrNull(windowProxy);
85 return true;
88 // Static assertion tests for the `binding_detail::ScriptableInterfaceType`
89 // helper template, used by `ToJSValue`.
90 namespace binding_detail {
91 static_assert(std::is_same_v<ScriptableInterfaceType<nsISupports>, nsISupports>,
92 "nsISupports works with ScriptableInterfaceType");
93 static_assert(
94 std::is_same_v<ScriptableInterfaceType<nsIGlobalObject>, nsISupports>,
95 "non-scriptable interfaces get a fallback");
96 static_assert(std::is_same_v<ScriptableInterfaceType<nsIObserver>, nsIObserver>,
97 "scriptable interfaces should get the correct type");
98 static_assert(std::is_same_v<ScriptableInterfaceType<nsIRunnable>, nsIRunnable>,
99 "scriptable interfaces should get the correct type");
100 class SingleScriptableInterface : public nsIObserver {};
101 static_assert(
102 std::is_same_v<ScriptableInterfaceType<SingleScriptableInterface>,
103 nsIObserver>,
104 "Concrete type with one scriptable interface picks the correct interface");
105 class MultiScriptableInterface : public nsIObserver, public nsIRunnable {};
106 static_assert(std::is_same_v<ScriptableInterfaceType<MultiScriptableInterface>,
107 nsISupports>,
108 "Concrete type with multiple scriptable interfaces falls back");
109 } // namespace binding_detail
110 } // namespace mozilla::dom