2015-05-03 22:32:37 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2014-04-10 22:57:07 +04:00
|
|
|
/* 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/ToJSValue.h"
|
2014-04-16 23:13:41 +04:00
|
|
|
#include "mozilla/dom/DOMException.h"
|
|
|
|
#include "mozilla/dom/Exceptions.h"
|
2016-02-10 01:40:31 +03:00
|
|
|
#include "mozilla/dom/Promise.h"
|
2019-01-02 16:27:05 +03:00
|
|
|
#include "mozilla/dom/WindowProxyHolder.h"
|
2014-04-10 22:57:07 +04:00
|
|
|
#include "nsAString.h"
|
|
|
|
#include "nsContentUtils.h"
|
2024-05-14 17:24:26 +03:00
|
|
|
#include "mozilla/StringBuffer.h"
|
2014-04-10 22:57:07 +04:00
|
|
|
#include "xpcpublic.h"
|
|
|
|
|
2020-11-04 20:04:01 +03:00
|
|
|
namespace mozilla::dom {
|
2014-04-10 22:57:07 +04:00
|
|
|
|
|
|
|
bool ToJSValue(JSContext* aCx, const nsAString& aArgument,
|
|
|
|
JS::MutableHandle<JS::Value> aValue) {
|
|
|
|
// Make sure we're called in a compartment
|
|
|
|
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
|
|
|
|
|
|
|
|
// XXXkhuey I'd love to use xpc::NonVoidStringToJsval here, but it requires
|
|
|
|
// a non-const nsAString for silly reasons.
|
2024-05-14 17:24:26 +03:00
|
|
|
mozilla::StringBuffer* sharedBuffer;
|
2014-04-10 22:57:07 +04:00
|
|
|
if (!XPCStringConvert::ReadableToJSVal(aCx, aArgument, &sharedBuffer,
|
|
|
|
aValue)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sharedBuffer) {
|
|
|
|
NS_ADDREF(sharedBuffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-12-14 14:12:11 +03:00
|
|
|
bool ToJSValue(JSContext* aCx, const nsACString& aArgument,
|
|
|
|
JS::MutableHandle<JS::Value> aValue) {
|
|
|
|
return UTF8StringToJsval(aCx, aArgument, aValue);
|
|
|
|
}
|
|
|
|
|
2014-04-16 23:13:41 +04:00
|
|
|
bool ToJSValue(JSContext* aCx, nsresult aArgument,
|
|
|
|
JS::MutableHandle<JS::Value> aValue) {
|
2017-01-19 11:03:03 +03:00
|
|
|
RefPtr<Exception> exception = CreateException(aArgument);
|
2014-04-16 23:13:41 +04:00
|
|
|
return ToJSValue(aCx, exception, aValue);
|
|
|
|
}
|
|
|
|
|
2020-02-14 18:42:30 +03:00
|
|
|
bool ToJSValue(JSContext* aCx, ErrorResult&& aArgument,
|
2014-10-30 18:12:09 +03:00
|
|
|
JS::MutableHandle<JS::Value> aValue) {
|
|
|
|
MOZ_ASSERT(aArgument.Failed());
|
2015-02-21 07:58:36 +03:00
|
|
|
MOZ_ASSERT(
|
|
|
|
!aArgument.IsUncatchableException(),
|
|
|
|
"Doesn't make sense to convert uncatchable exception to a JS value!");
|
2017-02-15 03:17:02 +03:00
|
|
|
MOZ_ALWAYS_TRUE(aArgument.MaybeSetPendingException(aCx));
|
|
|
|
MOZ_ALWAYS_TRUE(JS_GetPendingException(aCx, aValue));
|
2014-10-30 18:12:09 +03:00
|
|
|
JS_ClearPendingException(aCx);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2016-02-10 01:40:31 +03:00
|
|
|
bool ToJSValue(JSContext* aCx, Promise& aArgument,
|
|
|
|
JS::MutableHandle<JS::Value> aValue) {
|
|
|
|
aValue.setObject(*aArgument.PromiseObj());
|
2016-12-20 02:38:43 +03:00
|
|
|
return MaybeWrapObjectValue(aCx, aValue);
|
2016-02-10 01:40:31 +03:00
|
|
|
}
|
|
|
|
|
2019-01-02 16:27:05 +03:00
|
|
|
bool ToJSValue(JSContext* aCx, const WindowProxyHolder& aArgument,
|
|
|
|
JS::MutableHandle<JS::Value> aValue) {
|
|
|
|
BrowsingContext* bc = aArgument.get();
|
|
|
|
if (!bc) {
|
|
|
|
aValue.setNull();
|
|
|
|
return true;
|
|
|
|
}
|
2019-01-02 16:29:18 +03:00
|
|
|
JS::Rooted<JSObject*> windowProxy(aCx);
|
Bug 1529684 - Part 6: Store a mIsInProcess flag to preserve WindowProxy behaviour, r=farre
Currently when we have an in-process WindowProxy object, we will attempt
to either use the cached mWindowProxy value, or fetch the
nsGlobalWindowOuter object from through the nsDocShell. Unfortunately,
when the BrowsingContext is detached, we will fail to get the
nsGlobalWindowOuter object. This happens to be OK for our test cases, as
the cached mWindowProxy value doesn't have the chance to go away, but
isn't acceptable long-term.
These patches exascerbated that issue by causing the nsDocShell pointer
itself to be cleared when it is destroyed, which caused the Remote
WindowProxy logic to be triggered. To deal with that case, this patch
adds a new mIsInProcess flag to continue to act like the old code-path.
In the future, we will need to also handle ensuring that the
nsGlobalWindowOuter lives for long enough, however that is not being
done in this patch in order to land it sooner rather than later.
Depends on D22763
Differential Revision: https://phabricator.services.mozilla.com/D22764
--HG--
extra : moz-landing-system : lando
2019-03-14 21:50:54 +03:00
|
|
|
if (bc->IsInProcess()) {
|
2019-01-02 16:27:05 +03:00
|
|
|
windowProxy = bc->GetWindowProxy();
|
2019-01-02 16:29:18 +03:00
|
|
|
if (!windowProxy) {
|
|
|
|
nsPIDOMWindowOuter* window = bc->GetDOMWindow();
|
2019-01-03 23:31:05 +03:00
|
|
|
if (!window) {
|
|
|
|
// Torn down enough that we should just return null.
|
|
|
|
aValue.setNull();
|
|
|
|
return true;
|
|
|
|
}
|
2019-01-02 16:29:18 +03:00
|
|
|
if (!window->EnsureInnerWindow()) {
|
|
|
|
return Throw(aCx, NS_ERROR_UNEXPECTED);
|
|
|
|
}
|
|
|
|
windowProxy = bc->GetWindowProxy();
|
|
|
|
}
|
|
|
|
return ToJSValue(aCx, windowProxy, aValue);
|
|
|
|
}
|
|
|
|
|
2019-07-18 22:36:17 +03:00
|
|
|
if (!GetRemoteOuterWindowProxy(aCx, bc, /* aTransplantTo = */ nullptr,
|
|
|
|
&windowProxy)) {
|
2019-01-02 16:29:18 +03:00
|
|
|
return false;
|
2019-01-02 16:27:05 +03:00
|
|
|
}
|
2019-01-02 16:29:18 +03:00
|
|
|
aValue.setObjectOrNull(windowProxy);
|
|
|
|
return true;
|
2019-01-02 16:27:05 +03:00
|
|
|
}
|
|
|
|
|
2020-09-14 22:30:56 +03:00
|
|
|
// Static assertion tests for the `binding_detail::ScriptableInterfaceType`
|
|
|
|
// helper template, used by `ToJSValue`.
|
|
|
|
namespace binding_detail {
|
|
|
|
static_assert(std::is_same_v<ScriptableInterfaceType<nsISupports>, nsISupports>,
|
|
|
|
"nsISupports works with ScriptableInterfaceType");
|
|
|
|
static_assert(
|
|
|
|
std::is_same_v<ScriptableInterfaceType<nsIGlobalObject>, nsISupports>,
|
|
|
|
"non-scriptable interfaces get a fallback");
|
|
|
|
static_assert(std::is_same_v<ScriptableInterfaceType<nsIObserver>, nsIObserver>,
|
|
|
|
"scriptable interfaces should get the correct type");
|
|
|
|
static_assert(std::is_same_v<ScriptableInterfaceType<nsIRunnable>, nsIRunnable>,
|
|
|
|
"scriptable interfaces should get the correct type");
|
|
|
|
class SingleScriptableInterface : public nsIObserver {};
|
|
|
|
static_assert(
|
|
|
|
std::is_same_v<ScriptableInterfaceType<SingleScriptableInterface>,
|
|
|
|
nsIObserver>,
|
|
|
|
"Concrete type with one scriptable interface picks the correct interface");
|
|
|
|
class MultiScriptableInterface : public nsIObserver, public nsIRunnable {};
|
|
|
|
static_assert(std::is_same_v<ScriptableInterfaceType<MultiScriptableInterface>,
|
|
|
|
nsISupports>,
|
|
|
|
"Concrete type with multiple scriptable interfaces falls back");
|
|
|
|
} // namespace binding_detail
|
2020-11-04 20:04:01 +03:00
|
|
|
} // namespace mozilla::dom
|