tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ToJSValue.cpp (4167B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "mozilla/dom/ToJSValue.h"
      8 
      9 #include "mozilla/dom/DOMException.h"
     10 #include "mozilla/dom/Exceptions.h"
     11 #include "mozilla/dom/Promise.h"
     12 #include "mozilla/dom/WindowProxyHolder.h"
     13 #include "nsAString.h"
     14 #include "nsContentUtils.h"
     15 #include "xpcpublic.h"
     16 
     17 namespace mozilla::dom {
     18 
     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);
     24 }
     25 
     26 bool ToJSValue(JSContext* aCx, const nsACString& aArgument,
     27               JS::MutableHandle<JS::Value> aValue) {
     28  return UTF8StringToJsval(aCx, aArgument, aValue);
     29 }
     30 
     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);
     35 }
     36 
     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;
     47 }
     48 
     49 bool ToJSValue(JSContext* aCx, Promise& aArgument,
     50               JS::MutableHandle<JS::Value> aValue) {
     51  aValue.setObject(*aArgument.PromiseObj());
     52  return MaybeWrapObjectValue(aCx, aValue);
     53 }
     54 
     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;
     61  }
     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;
     71      }
     72      if (!window->EnsureInnerWindow()) {
     73        return Throw(aCx, NS_ERROR_UNEXPECTED);
     74      }
     75      windowProxy = bc->GetWindowProxy();
     76    }
     77    return ToJSValue(aCx, windowProxy, aValue);
     78  }
     79 
     80  if (!GetRemoteOuterWindowProxy(aCx, bc, /* aTransplantTo = */ nullptr,
     81                                 &windowProxy)) {
     82    return false;
     83  }
     84  aValue.setObjectOrNull(windowProxy);
     85  return true;
     86 }
     87 
     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