mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1181382: move declaration into namespace to resolve conflict. r=hsinyi (b1cbc67344) - Bug 1131470 - Part 3: Implement ScreenOrientation interface. r=baku (805ffd4d18) - Bug 1131470 - Part 4: Check sandboxing flag for orientation lock. r=baku (2896c9af4c) - Bug 1131470 - Part 5: Handle changes to active orientation lock. r=smaug (2550433007) - Bug 1131470 - Part 6: ScreenOrientation tests. r=baku (53e088ab98) - Bug 1193133 - Drop the document and window references from ServiceWorker. r=bkelly (ce09f526b8) - Bug 1186307 - part 1 - Unify the StructuredCloneCallbacks in WorkerPrivate.cpp, r=smaug (a109da831d) - pointer style (c26fa45b91) - Bug 1174971 - Introduce two variants of getOwnPropertyFromTargetIfSafe. r=gabor,r=arai (4bec0627ce) - reapply Bug 1131802 part 2. Allocate functions with reserved slots for DOM Xrays so we can store the Xray wrapper reference in those slots instead of as the function parent. r=peterv (ff39e220a3) - No bug - Add a bug number to the expected failure in message-event.html. (398f3e500a) - Bug 1164834: MessageEvents coming from postMessage should not be cancelable. r=Ms2ger (380ce180bf)
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/dom/ProfileTimelineMarkerBinding.h"
|
||||
#include "mozilla/dom/ScreenOrientation.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "mozilla/dom/workers/ServiceWorkerManager.h"
|
||||
#include "mozilla/EventStateManager.h"
|
||||
@@ -757,6 +758,7 @@ nsDocShell::nsDocShell()
|
||||
, mLoadedTransIndex(-1)
|
||||
, mSandboxFlags(0)
|
||||
, mFullscreenAllowed(CHECK_ATTRIBUTES)
|
||||
, mOrientationLock(eScreenOrientation_None)
|
||||
, mCreated(false)
|
||||
, mAllowSubframes(true)
|
||||
, mAllowPlugins(true)
|
||||
@@ -2560,6 +2562,18 @@ nsDocShell::SetFullscreenAllowed(bool aFullscreenAllowed)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ScreenOrientationInternal
|
||||
nsDocShell::OrientationLock()
|
||||
{
|
||||
return mOrientationLock;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocShell::SetOrientationLock(ScreenOrientationInternal aOrientationLock)
|
||||
{
|
||||
mOrientationLock = aOrientationLock;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetMayEnableCharacterEncodingMenu(
|
||||
bool* aMayEnableCharacterEncodingMenu)
|
||||
@@ -6065,6 +6079,16 @@ nsDocShell::SetIsActive(bool aIsActive)
|
||||
if (mScriptGlobal) {
|
||||
mScriptGlobal->SetIsBackground(!aIsActive);
|
||||
if (nsCOMPtr<nsIDocument> doc = mScriptGlobal->GetExtantDoc()) {
|
||||
if (aIsActive) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> parent;
|
||||
GetSameTypeParent(getter_AddRefs(parent));
|
||||
if (!parent) {
|
||||
// We only care about the top-level browsing context.
|
||||
uint16_t orientation = OrientationLock();
|
||||
ScreenOrientation::UpdateActiveOrientationLock(orientation);
|
||||
}
|
||||
}
|
||||
|
||||
doc->PostVisibilityUpdateEvent();
|
||||
}
|
||||
}
|
||||
@@ -10270,6 +10294,22 @@ nsDocShell::InternalLoad2(nsIURI* aURI,
|
||||
mTiming->NotifyUnloadAccepted(mCurrentURI);
|
||||
}
|
||||
|
||||
// Whenever a top-level browsing context is navigated, the user agent MUST
|
||||
// lock the orientation of the document to the document's default
|
||||
// orientation. We don't explicitly check for a top-level browsing context
|
||||
// here because orientation is only set on top-level browsing contexts.
|
||||
if (OrientationLock() != eScreenOrientation_None) {
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIDocShellTreeItem> parent;
|
||||
GetSameTypeParent(getter_AddRefs(parent));
|
||||
MOZ_ASSERT(!parent);
|
||||
#endif
|
||||
SetOrientationLock(eScreenOrientation_None);
|
||||
if (mIsActive) {
|
||||
ScreenOrientation::UpdateActiveOrientationLock(eScreenOrientation_None);
|
||||
}
|
||||
}
|
||||
|
||||
// Check for saving the presentation here, before calling Stop().
|
||||
// This is necessary so that we can catch any pending requests.
|
||||
// Since the new request has not been created yet, we pass null for the
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class EventTarget;
|
||||
typedef uint32_t ScreenOrientationInternal;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@@ -879,6 +880,10 @@ protected:
|
||||
};
|
||||
FullscreenAllowedState mFullscreenAllowed;
|
||||
|
||||
// The orientation lock as described by
|
||||
// https://w3c.github.io/screen-orientation/
|
||||
mozilla::dom::ScreenOrientationInternal mOrientationLock;
|
||||
|
||||
// Cached value of the "browser.xul.error_pages.enabled" preference.
|
||||
static bool sUseErrorPages;
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ interface nsITabParent;
|
||||
|
||||
typedef unsigned long nsLoadFlags;
|
||||
|
||||
[scriptable, builtinclass, uuid(97471054-0BC8-4A57-BBFE-6C255BCBBB67)]
|
||||
[scriptable, builtinclass, uuid(35a26f70-dbb9-450d-b634-cd0bbb9b8e13)]
|
||||
interface nsIDocShell : nsIDocShellTreeItem
|
||||
{
|
||||
/**
|
||||
@@ -920,6 +920,9 @@ interface nsIDocShell : nsIDocShellTreeItem
|
||||
|
||||
void setFullscreenAllowed(in boolean allowed);
|
||||
|
||||
[notxpcom] uint32_t orientationLock();
|
||||
[notxpcom] void setOrientationLock(in uint32_t orientationLock);
|
||||
|
||||
[noscript, infallible] attribute boolean affectPrivateSessionLifetime;
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,645 @@
|
||||
/* 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 "ScreenOrientation.h"
|
||||
#include "nsIDeviceSensors.h"
|
||||
#include "nsSandboxFlags.h"
|
||||
#include "nsScreen.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(ScreenOrientation,
|
||||
DOMEventTargetHelper,
|
||||
mScreen);
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ScreenOrientation)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(ScreenOrientation, DOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(ScreenOrientation, DOMEventTargetHelper)
|
||||
|
||||
static OrientationType
|
||||
InternalOrientationToType(ScreenOrientationInternal aOrientation)
|
||||
{
|
||||
switch (aOrientation) {
|
||||
case eScreenOrientation_PortraitPrimary:
|
||||
return OrientationType::Portrait_primary;
|
||||
case eScreenOrientation_PortraitSecondary:
|
||||
return OrientationType::Portrait_secondary;
|
||||
case eScreenOrientation_LandscapePrimary:
|
||||
return OrientationType::Landscape_primary;
|
||||
case eScreenOrientation_LandscapeSecondary:
|
||||
return OrientationType::Landscape_secondary;
|
||||
default:
|
||||
MOZ_CRASH("Bad aOrientation value");
|
||||
}
|
||||
}
|
||||
|
||||
static ScreenOrientationInternal
|
||||
OrientationTypeToInternal(OrientationType aOrientation)
|
||||
{
|
||||
switch (aOrientation) {
|
||||
case OrientationType::Portrait_primary:
|
||||
return eScreenOrientation_PortraitPrimary;
|
||||
case OrientationType::Portrait_secondary:
|
||||
return eScreenOrientation_PortraitSecondary;
|
||||
case OrientationType::Landscape_primary:
|
||||
return eScreenOrientation_LandscapePrimary;
|
||||
case OrientationType::Landscape_secondary:
|
||||
return eScreenOrientation_LandscapeSecondary;
|
||||
default:
|
||||
MOZ_CRASH("Bad aOrientation value");
|
||||
}
|
||||
}
|
||||
|
||||
ScreenOrientation::ScreenOrientation(nsPIDOMWindow* aWindow, nsScreen* aScreen)
|
||||
: DOMEventTargetHelper(aWindow), mScreen(aScreen)
|
||||
{
|
||||
MOZ_ASSERT(aWindow);
|
||||
MOZ_ASSERT(aScreen);
|
||||
|
||||
hal::RegisterScreenConfigurationObserver(this);
|
||||
|
||||
hal::ScreenConfiguration config;
|
||||
hal::GetCurrentScreenConfiguration(&config);
|
||||
mType = InternalOrientationToType(config.orientation());
|
||||
mAngle = config.angle();
|
||||
|
||||
nsIDocument* doc = GetResponsibleDocument();
|
||||
if (doc) {
|
||||
doc->SetCurrentOrientation(mType, mAngle);
|
||||
}
|
||||
}
|
||||
|
||||
ScreenOrientation::~ScreenOrientation()
|
||||
{
|
||||
hal::UnregisterScreenConfigurationObserver(this);
|
||||
MOZ_ASSERT(!mFullScreenListener);
|
||||
}
|
||||
|
||||
class ScreenOrientation::FullScreenEventListener final : public nsIDOMEventListener
|
||||
{
|
||||
~FullScreenEventListener() {}
|
||||
public:
|
||||
FullScreenEventListener() {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
};
|
||||
|
||||
class ScreenOrientation::VisibleEventListener final : public nsIDOMEventListener
|
||||
{
|
||||
~VisibleEventListener() {}
|
||||
public:
|
||||
VisibleEventListener() {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
};
|
||||
|
||||
class ScreenOrientation::LockOrientationTask final : public nsIRunnable
|
||||
{
|
||||
~LockOrientationTask();
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
LockOrientationTask(ScreenOrientation* aScreenOrientation,
|
||||
Promise* aPromise,
|
||||
ScreenOrientationInternal aOrientationLock,
|
||||
nsIDocument* aDocument,
|
||||
bool aIsFullScreen);
|
||||
protected:
|
||||
bool OrientationLockContains(OrientationType aOrientationType);
|
||||
|
||||
nsRefPtr<ScreenOrientation> mScreenOrientation;
|
||||
nsRefPtr<Promise> mPromise;
|
||||
ScreenOrientationInternal mOrientationLock;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
bool mIsFullScreen;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(ScreenOrientation::LockOrientationTask, nsIRunnable)
|
||||
|
||||
ScreenOrientation::LockOrientationTask::LockOrientationTask(
|
||||
ScreenOrientation* aScreenOrientation, Promise* aPromise,
|
||||
ScreenOrientationInternal aOrientationLock,
|
||||
nsIDocument* aDocument, bool aIsFullScreen)
|
||||
: mScreenOrientation(aScreenOrientation), mPromise(aPromise),
|
||||
mOrientationLock(aOrientationLock), mDocument(aDocument),
|
||||
mIsFullScreen(aIsFullScreen)
|
||||
{
|
||||
MOZ_ASSERT(aScreenOrientation);
|
||||
MOZ_ASSERT(aPromise);
|
||||
MOZ_ASSERT(aDocument);
|
||||
}
|
||||
|
||||
ScreenOrientation::LockOrientationTask::~LockOrientationTask()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
ScreenOrientation::LockOrientationTask::OrientationLockContains(
|
||||
OrientationType aOrientationType)
|
||||
{
|
||||
return mOrientationLock & OrientationTypeToInternal(aOrientationType);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ScreenOrientation::LockOrientationTask::Run()
|
||||
{
|
||||
// Step to lock the orientation as defined in the spec.
|
||||
|
||||
if (mDocument->GetOrientationPendingPromise() != mPromise) {
|
||||
// The document's pending promise is not associated with this task
|
||||
// to lock orientation. There has since been another request to
|
||||
// lock orientation, thus we don't need to do anything. Old promise
|
||||
// should be been rejected.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mDocument->Hidden()) {
|
||||
// Active orientation lock is not the document's orientation lock.
|
||||
mPromise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
mDocument->SetOrientationPendingPromise(nullptr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mOrientationLock == eScreenOrientation_None) {
|
||||
mScreenOrientation->UnlockDeviceOrientation();
|
||||
mPromise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
mDocument->SetOrientationPendingPromise(nullptr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
bool result = mScreenOrientation->LockDeviceOrientation(mOrientationLock,
|
||||
mIsFullScreen, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!result)) {
|
||||
mPromise->MaybeReject(NS_ERROR_UNEXPECTED);
|
||||
mDocument->SetOrientationPendingPromise(nullptr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (OrientationLockContains(mDocument->CurrentOrientationType()) ||
|
||||
(mOrientationLock == eScreenOrientation_Default &&
|
||||
mDocument->CurrentOrientationAngle() == 0)) {
|
||||
// Orientation lock will not cause an orientation change.
|
||||
mPromise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
mDocument->SetOrientationPendingPromise(nullptr);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
ScreenOrientation::Lock(OrientationLockType aOrientation, ErrorResult& aRv)
|
||||
{
|
||||
ScreenOrientationInternal orientation = eScreenOrientation_None;
|
||||
|
||||
switch (aOrientation) {
|
||||
case OrientationLockType::Any:
|
||||
orientation = eScreenOrientation_PortraitPrimary |
|
||||
eScreenOrientation_PortraitSecondary |
|
||||
eScreenOrientation_LandscapePrimary |
|
||||
eScreenOrientation_LandscapeSecondary;
|
||||
break;
|
||||
case OrientationLockType::Natural:
|
||||
orientation |= eScreenOrientation_Default;
|
||||
break;
|
||||
case OrientationLockType::Landscape:
|
||||
orientation = eScreenOrientation_LandscapePrimary |
|
||||
eScreenOrientation_LandscapeSecondary;
|
||||
break;
|
||||
case OrientationLockType::Portrait:
|
||||
orientation = eScreenOrientation_PortraitPrimary |
|
||||
eScreenOrientation_PortraitSecondary;
|
||||
break;
|
||||
case OrientationLockType::Portrait_primary:
|
||||
orientation = eScreenOrientation_PortraitPrimary;
|
||||
break;
|
||||
case OrientationLockType::Portrait_secondary:
|
||||
orientation = eScreenOrientation_PortraitSecondary;
|
||||
break;
|
||||
case OrientationLockType::Landscape_primary:
|
||||
orientation = eScreenOrientation_LandscapePrimary;
|
||||
break;
|
||||
case OrientationLockType::Landscape_secondary:
|
||||
orientation = eScreenOrientation_LandscapeSecondary;
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("Unexpected orientation type");
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return LockInternal(orientation, aRv);
|
||||
}
|
||||
|
||||
static inline void
|
||||
AbortOrientationPromises(nsIDocShell* aDocShell)
|
||||
{
|
||||
MOZ_ASSERT(aDocShell);
|
||||
|
||||
nsIDocument* doc = aDocShell->GetDocument();
|
||||
if (doc) {
|
||||
Promise* promise = doc->GetOrientationPendingPromise();
|
||||
if (promise) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
|
||||
doc->SetOrientationPendingPromise(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t childCount;
|
||||
aDocShell->GetChildCount(&childCount);
|
||||
for (int32_t i = 0; i < childCount; i++) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> child;
|
||||
if (NS_SUCCEEDED(aDocShell->GetChildAt(i, getter_AddRefs(child)))) {
|
||||
nsCOMPtr<nsIDocShell> childShell(do_QueryInterface(child));
|
||||
if (childShell) {
|
||||
AbortOrientationPromises(childShell);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
ScreenOrientation::LockInternal(ScreenOrientationInternal aOrientation, ErrorResult& aRv)
|
||||
{
|
||||
// Steps to apply an orientation lock as defined in spec.
|
||||
|
||||
nsIDocument* doc = GetResponsibleDocument();
|
||||
if (NS_WARN_IF(!doc)) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> owner = GetOwner();
|
||||
if (NS_WARN_IF(!owner)) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = owner->GetDocShell();
|
||||
if (NS_WARN_IF(!docShell)) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(owner);
|
||||
MOZ_ASSERT(go);
|
||||
nsRefPtr<Promise> p = Promise::Create(go, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK)
|
||||
// User agent does not support locking the screen orientation.
|
||||
p->MaybeReject(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return p.forget();
|
||||
#else
|
||||
LockPermission perm = GetLockOrientationPermission(true);
|
||||
if (perm == LOCK_DENIED) {
|
||||
p->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> root;
|
||||
docShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
|
||||
nsCOMPtr<nsIDocShell> rootShell(do_QueryInterface(root));
|
||||
if (!rootShell) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rootShell->SetOrientationLock(aOrientation);
|
||||
AbortOrientationPromises(rootShell);
|
||||
|
||||
doc->SetOrientationPendingPromise(p);
|
||||
|
||||
nsCOMPtr<nsIRunnable> lockOrientationTask =
|
||||
new LockOrientationTask(this, p, aOrientation, doc,
|
||||
perm == FULLSCREEN_LOCK_ALLOWED);
|
||||
aRv = NS_DispatchToMainThread(lockOrientationTask);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return p.forget();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
ScreenOrientation::LockDeviceOrientation(ScreenOrientationInternal aOrientation,
|
||||
bool aIsFullScreen, ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<EventTarget> target = do_QueryInterface(GetOwner()->GetDoc());
|
||||
// We need to register a listener so we learn when we leave full-screen
|
||||
// and when we will have to unlock the screen.
|
||||
// This needs to be done before LockScreenOrientation call to make sure
|
||||
// the locking can be unlocked.
|
||||
if (aIsFullScreen && !target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!hal::LockScreenOrientation(aOrientation))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We are fullscreen and lock has been accepted.
|
||||
if (aIsFullScreen && !mFullScreenListener) {
|
||||
mFullScreenListener = new FullScreenEventListener();
|
||||
aRv = target->AddSystemEventListener(NS_LITERAL_STRING("mozfullscreenchange"),
|
||||
mFullScreenListener, /* useCapture = */ true);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ScreenOrientation::Unlock(ErrorResult& aRv)
|
||||
{
|
||||
nsRefPtr<Promise> p = LockInternal(eScreenOrientation_None, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
ScreenOrientation::UnlockDeviceOrientation()
|
||||
{
|
||||
hal::UnlockScreenOrientation();
|
||||
|
||||
if (!mFullScreenListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove event listener in case of fullscreen lock.
|
||||
nsCOMPtr<EventTarget> target = do_QueryInterface(GetOwner()->GetDoc());
|
||||
if (target) {
|
||||
nsresult rv = target->RemoveSystemEventListener(NS_LITERAL_STRING("mozfullscreenchange"),
|
||||
mFullScreenListener, /* useCapture */ true);
|
||||
NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
|
||||
mFullScreenListener = nullptr;
|
||||
}
|
||||
|
||||
OrientationType
|
||||
ScreenOrientation::DeviceType() const
|
||||
{
|
||||
return mType;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
ScreenOrientation::DeviceAngle() const
|
||||
{
|
||||
return mAngle;
|
||||
}
|
||||
|
||||
OrientationType
|
||||
ScreenOrientation::GetType(ErrorResult& aRv) const
|
||||
{
|
||||
nsIDocument* doc = GetResponsibleDocument();
|
||||
if (!doc) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return OrientationType::Portrait_primary;
|
||||
}
|
||||
|
||||
return doc->CurrentOrientationType();
|
||||
}
|
||||
|
||||
uint16_t
|
||||
ScreenOrientation::GetAngle(ErrorResult& aRv) const
|
||||
{
|
||||
nsIDocument* doc = GetResponsibleDocument();
|
||||
if (!doc) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return doc->CurrentOrientationAngle();
|
||||
}
|
||||
|
||||
ScreenOrientation::LockPermission
|
||||
ScreenOrientation::GetLockOrientationPermission(bool aCheckSandbox) const
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> owner = GetOwner();
|
||||
if (!owner) {
|
||||
return LOCK_DENIED;
|
||||
}
|
||||
|
||||
// Chrome can always lock the screen orientation.
|
||||
nsIDocShell* docShell = owner->GetDocShell();
|
||||
if (docShell && docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
|
||||
return LOCK_ALLOWED;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = owner->GetDoc();
|
||||
if (!doc || doc->Hidden()) {
|
||||
return LOCK_DENIED;
|
||||
}
|
||||
|
||||
// Sandboxed without "allow-orientation-lock"
|
||||
if (aCheckSandbox && doc->GetSandboxFlags() & SANDBOXED_ORIENTATION_LOCK) {
|
||||
return LOCK_DENIED;
|
||||
}
|
||||
|
||||
// Apps can always lock the screen orientation.
|
||||
if (doc->NodePrincipal()->GetAppStatus() >=
|
||||
nsIPrincipal::APP_STATUS_INSTALLED) {
|
||||
return LOCK_ALLOWED;
|
||||
}
|
||||
|
||||
if (Preferences::GetBool("dom.screenorientation.testing.non_fullscreen_lock_allow",
|
||||
false)) {
|
||||
return LOCK_ALLOWED;
|
||||
}
|
||||
|
||||
// Other content must be full-screen in order to lock orientation.
|
||||
return doc->MozFullScreen() ? FULLSCREEN_LOCK_ALLOWED : LOCK_DENIED;
|
||||
}
|
||||
|
||||
nsIDocument*
|
||||
ScreenOrientation::GetResponsibleDocument() const
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> owner = GetOwner();
|
||||
if (!owner) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return owner->GetDoc();
|
||||
}
|
||||
|
||||
void
|
||||
ScreenOrientation::Notify(const hal::ScreenConfiguration& aConfiguration)
|
||||
{
|
||||
nsIDocument* doc = GetResponsibleDocument();
|
||||
if (!doc) {
|
||||
return;
|
||||
}
|
||||
|
||||
ScreenOrientationInternal orientation = aConfiguration.orientation();
|
||||
if (orientation != eScreenOrientation_PortraitPrimary &&
|
||||
orientation != eScreenOrientation_PortraitSecondary &&
|
||||
orientation != eScreenOrientation_LandscapePrimary &&
|
||||
orientation != eScreenOrientation_LandscapeSecondary) {
|
||||
// The platform may notify of some other values from
|
||||
// an orientation lock, but we only care about real
|
||||
// changes to screen orientation which result in one of
|
||||
// the values we care about.
|
||||
return;
|
||||
}
|
||||
|
||||
OrientationType previousOrientation = mType;
|
||||
mAngle = aConfiguration.angle();
|
||||
mType = InternalOrientationToType(orientation);
|
||||
|
||||
nsresult rv;
|
||||
if (mScreen && mType != previousOrientation) {
|
||||
// Use of mozorientationchange is deprecated.
|
||||
rv = mScreen->DispatchTrustedEvent(NS_LITERAL_STRING("mozorientationchange"));
|
||||
NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
|
||||
if (doc->Hidden() && !mVisibleListener) {
|
||||
mVisibleListener = new VisibleEventListener();
|
||||
rv = doc->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
|
||||
mVisibleListener, /* useCapture = */ true);
|
||||
NS_WARN_IF(NS_FAILED(rv));
|
||||
return;
|
||||
}
|
||||
|
||||
if (mType != doc->CurrentOrientationType()) {
|
||||
doc->SetCurrentOrientation(mType, mAngle);
|
||||
|
||||
Promise* pendingPromise = doc->GetOrientationPendingPromise();
|
||||
if (pendingPromise) {
|
||||
pendingPromise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
doc->SetOrientationPendingPromise(nullptr);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableMethod(this,
|
||||
&ScreenOrientation::DispatchChangeEvent);
|
||||
rv = NS_DispatchToMainThread(runnable);
|
||||
NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScreenOrientation::UpdateActiveOrientationLock(ScreenOrientationInternal aOrientation)
|
||||
{
|
||||
if (aOrientation == eScreenOrientation_None) {
|
||||
hal::UnlockScreenOrientation();
|
||||
} else {
|
||||
hal::LockScreenOrientation(aOrientation);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScreenOrientation::DispatchChangeEvent()
|
||||
{
|
||||
nsresult rv = DispatchTrustedEvent(NS_LITERAL_STRING("change"));
|
||||
NS_WARN_IF(NS_FAILED(rv));
|
||||
}
|
||||
|
||||
JSObject*
|
||||
ScreenOrientation::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return ScreenOrientationBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(ScreenOrientation::VisibleEventListener, nsIDOMEventListener)
|
||||
|
||||
NS_IMETHODIMP
|
||||
ScreenOrientation::VisibleEventListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
// Document may have become visible, if the page is visible, run the steps
|
||||
// following the "now visible algorithm" as specified.
|
||||
nsCOMPtr<EventTarget> target = aEvent->InternalDOMEvent()->GetCurrentTarget();
|
||||
MOZ_ASSERT(target);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(target);
|
||||
if (!doc || doc->Hidden()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsGlobalWindow* win = static_cast<nsGlobalWindow*>(doc->GetInnerWindow());
|
||||
if (!win) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
nsScreen* screen = win->GetScreen(rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(screen);
|
||||
ScreenOrientation* orientation = screen->Orientation();
|
||||
MOZ_ASSERT(orientation);
|
||||
|
||||
rv = target->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
|
||||
this, true);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
if (doc->CurrentOrientationType() != orientation->DeviceType()) {
|
||||
doc->SetCurrentOrientation(orientation->DeviceType(), orientation->DeviceAngle());
|
||||
|
||||
Promise* pendingPromise = doc->GetOrientationPendingPromise();
|
||||
if (pendingPromise) {
|
||||
pendingPromise->MaybeResolve(JS::UndefinedHandleValue);
|
||||
doc->SetOrientationPendingPromise(nullptr);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable = NS_NewRunnableMethod(orientation,
|
||||
&ScreenOrientation::DispatchChangeEvent);
|
||||
rv = NS_DispatchToMainThread(runnable);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(ScreenOrientation::FullScreenEventListener, nsIDOMEventListener)
|
||||
|
||||
NS_IMETHODIMP
|
||||
ScreenOrientation::FullScreenEventListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsAutoString eventType;
|
||||
aEvent->GetType(eventType);
|
||||
|
||||
MOZ_ASSERT(eventType.EqualsLiteral("mozfullscreenchange"));
|
||||
#endif
|
||||
|
||||
nsCOMPtr<EventTarget> target = aEvent->InternalDOMEvent()->GetCurrentTarget();
|
||||
MOZ_ASSERT(target);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(target);
|
||||
MOZ_ASSERT(doc);
|
||||
|
||||
// We have to make sure that the event we got is the event sent when
|
||||
// fullscreen is disabled because we could get one when fullscreen
|
||||
// got enabled if the lock call is done at the same moment.
|
||||
if (doc->MozFullScreen()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
hal::UnlockScreenOrientation();
|
||||
|
||||
nsresult rv = target->RemoveSystemEventListener(NS_LITERAL_STRING("mozfullscreenchange"),
|
||||
this, true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -7,9 +7,16 @@
|
||||
#ifndef mozilla_dom_ScreenOrientation_h
|
||||
#define mozilla_dom_ScreenOrientation_h
|
||||
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/dom/ScreenOrientationBinding.h"
|
||||
#include "mozilla/HalScreenConfiguration.h"
|
||||
|
||||
class nsScreen;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class Promise;
|
||||
// Make sure that any change to ScreenOrientationInternal values are
|
||||
// also made in mobile/android/base/GeckoScreenOrientation.java
|
||||
typedef uint32_t ScreenOrientationInternal;
|
||||
@@ -23,6 +30,90 @@ static const ScreenOrientationInternal eScreenOrientation_LandscapeSecondary = 1
|
||||
//it could be PortraitPrimary or LandscapePrimary depends on display resolution
|
||||
static const ScreenOrientationInternal eScreenOrientation_Default = 1u << 4;
|
||||
|
||||
class ScreenOrientation final : public DOMEventTargetHelper,
|
||||
public mozilla::hal::ScreenConfigurationObserver
|
||||
{
|
||||
// nsScreen has deprecated API that shares implementation.
|
||||
friend class ::nsScreen;
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ScreenOrientation, mozilla::DOMEventTargetHelper)
|
||||
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(mozilla::DOMEventTargetHelper)
|
||||
|
||||
IMPL_EVENT_HANDLER(change)
|
||||
|
||||
ScreenOrientation(nsPIDOMWindow* aWindow, nsScreen* aScreen);
|
||||
|
||||
already_AddRefed<Promise> Lock(OrientationLockType aOrientation,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void Unlock(ErrorResult& aRv);
|
||||
|
||||
// DeviceType and DeviceAngle gets the current type and angle of the device.
|
||||
OrientationType DeviceType() const;
|
||||
uint16_t DeviceAngle() const;
|
||||
|
||||
// GetType and GetAngle gets the type and angle of the responsible document
|
||||
// (as defined in specification).
|
||||
OrientationType GetType(ErrorResult& aRv) const;
|
||||
uint16_t GetAngle(ErrorResult& aRv) const;
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
void Notify(const mozilla::hal::ScreenConfiguration& aConfiguration) override;
|
||||
|
||||
static void UpdateActiveOrientationLock(ScreenOrientationInternal aOrientation);
|
||||
|
||||
private:
|
||||
virtual ~ScreenOrientation();
|
||||
|
||||
// Listener to unlock orientation if we leave fullscreen.
|
||||
class FullScreenEventListener;
|
||||
|
||||
// Listener to update document's orienation lock when document becomes
|
||||
// visible.
|
||||
class VisibleEventListener;
|
||||
|
||||
// Task to run step to lock orientation as defined in specification.
|
||||
class LockOrientationTask;
|
||||
|
||||
enum LockPermission {
|
||||
LOCK_DENIED,
|
||||
FULLSCREEN_LOCK_ALLOWED,
|
||||
LOCK_ALLOWED
|
||||
};
|
||||
|
||||
// This method calls into the HAL to lock the device and sets
|
||||
// up listeners for full screen change.
|
||||
bool LockDeviceOrientation(ScreenOrientationInternal aOrientation,
|
||||
bool aIsFullscreen, ErrorResult& aRv);
|
||||
|
||||
// This method calls in to the HAL to unlock the device and removes
|
||||
// full screen change listener.
|
||||
void UnlockDeviceOrientation();
|
||||
|
||||
// This method performs the same function as |Lock| except it takes
|
||||
// a ScreenOrientationInternal argument instead of an OrientationType.
|
||||
// This method exists in order to share implementation with nsScreen that
|
||||
// uses ScreenOrientationInternal.
|
||||
already_AddRefed<Promise> LockInternal(ScreenOrientationInternal aOrientation,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void DispatchChangeEvent();
|
||||
|
||||
LockPermission GetLockOrientationPermission(bool aCheckSandbox) const;
|
||||
|
||||
// Gets the responsible document as defined in the spec.
|
||||
nsIDocument* GetResponsibleDocument() const;
|
||||
|
||||
nsRefPtr<nsScreen> mScreen;
|
||||
nsRefPtr<FullScreenEventListener> mFullScreenListener;
|
||||
nsRefPtr<VisibleEventListener> mVisibleListener;
|
||||
OrientationType mType;
|
||||
uint16_t mAngle;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
@@ -7,11 +7,18 @@
|
||||
#include "StructuredCloneHelper.h"
|
||||
|
||||
#include "ImageContainer.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
#include "mozilla/dom/BlobBinding.h"
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/FileList.h"
|
||||
#include "mozilla/dom/FileListBinding.h"
|
||||
#include "mozilla/dom/ImageBitmap.h"
|
||||
#include "mozilla/dom/ImageBitmapBinding.h"
|
||||
#include "mozilla/dom/MessagePort.h"
|
||||
#include "mozilla/dom/MessagePortBinding.h"
|
||||
#include "mozilla/dom/PMessagePort.h"
|
||||
#include "mozilla/dom/StructuredCloneTags.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "nsTArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
namespace layers {
|
||||
class Image;
|
||||
}
|
||||
|
||||
@@ -333,6 +333,7 @@ UNIFIED_SOURCES += [
|
||||
'ProcessGlobal.cpp',
|
||||
'ResponsiveImageSelector.cpp',
|
||||
'SameProcessMessageQueue.cpp',
|
||||
'ScreenOrientation.cpp',
|
||||
'ScriptSettings.cpp',
|
||||
'ShadowRoot.cpp',
|
||||
'StructuredCloneHelper.cpp',
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
|
||||
// Undefine LoadImage to prevent naming conflict with Windows.
|
||||
#undef LoadImage
|
||||
|
||||
class nsAString;
|
||||
class nsIDocument;
|
||||
class nsStyledElementNotElementCSSInlineStyle;
|
||||
|
||||
@@ -1341,6 +1341,7 @@ nsContentUtils::ParseSandboxAttributeToFlags(const nsAttrValue* sandboxAttr)
|
||||
| SANDBOXED_SCRIPTS
|
||||
| SANDBOXED_AUTOMATIC_FEATURES
|
||||
| SANDBOXED_POINTER_LOCK
|
||||
| SANDBOXED_ORIENTATION_LOCK
|
||||
| SANDBOXED_DOMAIN;
|
||||
|
||||
// Macro for updating the flag according to the keywords
|
||||
@@ -1352,6 +1353,7 @@ nsContentUtils::ParseSandboxAttributeToFlags(const nsAttrValue* sandboxAttr)
|
||||
IF_KEYWORD(allowscripts, SANDBOXED_SCRIPTS | SANDBOXED_AUTOMATIC_FEATURES)
|
||||
IF_KEYWORD(allowtopnavigation, SANDBOXED_TOPLEVEL_NAVIGATION)
|
||||
IF_KEYWORD(allowpointerlock, SANDBOXED_POINTER_LOCK)
|
||||
IF_KEYWORD(alloworientationlock, SANDBOXED_ORIENTATION_LOCK)
|
||||
IF_KEYWORD(allowpopups, SANDBOXED_AUXILIARY_NAVIGATION)
|
||||
|
||||
return out;
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "nsQueryObject.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsScreen.h"
|
||||
|
||||
#include "mozilla/AsyncEventDispatcher.h"
|
||||
#include "mozilla/BasicEvents.h"
|
||||
@@ -1922,6 +1923,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFirstBaseNodeWithHref)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMImplementation)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImageMaps)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOrientationPendingPromise)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOriginalDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCachedEncoder)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStateObjectCached)
|
||||
@@ -2022,6 +2024,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildrenCollection)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRegistry)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMasterDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOrientationPendingPromise)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mImportManager)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSubImportLinks)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFontFaceSet)
|
||||
@@ -12032,6 +12035,38 @@ nsDocument::IsFullScreenEnabled(bool aCallerIsChrome, bool aLogFailure)
|
||||
return allowed;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
nsDocument::CurrentOrientationAngle() const
|
||||
{
|
||||
return mCurrentOrientationAngle;
|
||||
}
|
||||
|
||||
OrientationType
|
||||
nsDocument::CurrentOrientationType() const
|
||||
{
|
||||
return mCurrentOrientationType;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::SetCurrentOrientation(mozilla::dom::OrientationType aType,
|
||||
uint16_t aAngle)
|
||||
{
|
||||
mCurrentOrientationType = aType;
|
||||
mCurrentOrientationAngle = aAngle;
|
||||
}
|
||||
|
||||
Promise*
|
||||
nsDocument::GetOrientationPendingPromise() const
|
||||
{
|
||||
return mOrientationPendingPromise;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::SetOrientationPendingPromise(Promise* aPromise)
|
||||
{
|
||||
mOrientationPendingPromise = aPromise;
|
||||
}
|
||||
|
||||
static void
|
||||
DispatchPointerLockChange(nsIDocument* aTarget)
|
||||
{
|
||||
|
||||
@@ -1273,6 +1273,13 @@ public:
|
||||
bool SetPointerLock(Element* aElement, int aCursorStyle);
|
||||
static void UnlockPointer(nsIDocument* aDoc = nullptr);
|
||||
|
||||
void SetCurrentOrientation(mozilla::dom::OrientationType aType,
|
||||
uint16_t aAngle) override;
|
||||
uint16_t CurrentOrientationAngle() const override;
|
||||
mozilla::dom::OrientationType CurrentOrientationType() const override;
|
||||
void SetOrientationPendingPromise(mozilla::dom::Promise* aPromise) override;
|
||||
mozilla::dom::Promise* GetOrientationPendingPromise() const override;
|
||||
|
||||
// This method may fire a DOM event; if it does so it will happen
|
||||
// synchronously.
|
||||
void UpdateVisibilityState();
|
||||
@@ -1510,6 +1517,8 @@ protected:
|
||||
virtual nsIScriptGlobalObject* GetScriptHandlingObjectInternal() const override;
|
||||
virtual bool InternalAllowXULXBL() override;
|
||||
|
||||
void UpdateScreenOrientation();
|
||||
|
||||
#define NS_DOCUMENT_NOTIFY_OBSERVERS(func_, params_) \
|
||||
NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers, nsIDocumentObserver, \
|
||||
func_, params_);
|
||||
@@ -1674,6 +1683,13 @@ public:
|
||||
|
||||
bool mAsyncFullscreenPending:1;
|
||||
|
||||
// ScreenOrientation "pending promise" as described by
|
||||
// http://www.w3.org/TR/screen-orientation/
|
||||
nsRefPtr<mozilla::dom::Promise> mOrientationPendingPromise;
|
||||
|
||||
uint16_t mCurrentOrientationAngle;
|
||||
mozilla::dom::OrientationType mCurrentOrientationType;
|
||||
|
||||
// Whether we're observing the "app-theme-changed" observer service
|
||||
// notification. We need to keep track of this because we might get multiple
|
||||
// OnPageShow notifications in a row without an OnPageHide in between, if
|
||||
|
||||
@@ -79,6 +79,7 @@ GK_ATOM(allowevents, "allowevents")
|
||||
GK_ATOM(allownegativeassertions, "allownegativeassertions")
|
||||
GK_ATOM(allowforms,"allow-forms")
|
||||
GK_ATOM(allowfullscreen, "allowfullscreen")
|
||||
GK_ATOM(alloworientationlock,"allow-orientation-lock")
|
||||
GK_ATOM(allowpointerlock,"allow-pointer-lock")
|
||||
GK_ATOM(allowpopups,"allow-popups")
|
||||
GK_ATOM(allowsameorigin,"allow-same-origin")
|
||||
|
||||
@@ -132,7 +132,9 @@ class MediaQueryList;
|
||||
class GlobalObject;
|
||||
class NodeFilter;
|
||||
class NodeIterator;
|
||||
enum class OrientationType : uint32_t;
|
||||
class ProcessingInstruction;
|
||||
class Promise;
|
||||
class Selection;
|
||||
class StyleSheetList;
|
||||
class SVGDocument;
|
||||
@@ -1204,6 +1206,14 @@ public:
|
||||
|
||||
static void UnlockPointer(nsIDocument* aDoc = nullptr);
|
||||
|
||||
// ScreenOrientation related APIs
|
||||
|
||||
virtual void SetCurrentOrientation(mozilla::dom::OrientationType aType,
|
||||
uint16_t aAngle) = 0;
|
||||
virtual uint16_t CurrentOrientationAngle() const = 0;
|
||||
virtual mozilla::dom::OrientationType CurrentOrientationType() const = 0;
|
||||
virtual void SetOrientationPendingPromise(mozilla::dom::Promise* aPromise) = 0;
|
||||
virtual mozilla::dom::Promise* GetOrientationPendingPromise() const = 0;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -76,4 +76,9 @@ const unsigned long SANDBOXED_DOMAIN = 0x100;
|
||||
* showModalDialog() method.
|
||||
*/
|
||||
const unsigned long SANDBOXED_AUXILIARY_NAVIGATION = 0x200;
|
||||
|
||||
/**
|
||||
* This flag prevents locking screen orientation.
|
||||
*/
|
||||
const unsigned long SANDBOXED_ORIENTATION_LOCK = 0x400;
|
||||
#endif
|
||||
|
||||
+23
-136
@@ -4,7 +4,6 @@
|
||||
* 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/Hal.h"
|
||||
#include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
|
||||
#include "mozilla/dom/ScreenBinding.h"
|
||||
#include "nsScreen.h"
|
||||
@@ -36,36 +35,32 @@ nsScreen::Create(nsPIDOMWindow* aWindow)
|
||||
NS_ENSURE_TRUE(sgo, nullptr);
|
||||
|
||||
nsRefPtr<nsScreen> screen = new nsScreen(aWindow);
|
||||
|
||||
hal::RegisterScreenConfigurationObserver(screen);
|
||||
hal::ScreenConfiguration config;
|
||||
hal::GetCurrentScreenConfiguration(&config);
|
||||
screen->mOrientationInternal = config.orientation();
|
||||
|
||||
return screen.forget();
|
||||
}
|
||||
|
||||
nsScreen::nsScreen(nsPIDOMWindow* aWindow)
|
||||
: DOMEventTargetHelper(aWindow)
|
||||
, mEventListener(nullptr)
|
||||
, mScreenOrientation(new ScreenOrientation(aWindow, this))
|
||||
{
|
||||
}
|
||||
|
||||
nsScreen::~nsScreen()
|
||||
{
|
||||
MOZ_ASSERT(!mEventListener);
|
||||
hal::UnregisterScreenConfigurationObserver(this);
|
||||
}
|
||||
|
||||
|
||||
// QueryInterface implementation for nsScreen
|
||||
NS_INTERFACE_MAP_BEGIN(nsScreen)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsScreen)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMScreen)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsScreen, DOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(nsScreen, DOMEventTargetHelper)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(nsScreen,
|
||||
DOMEventTargetHelper,
|
||||
mScreenOrientation)
|
||||
|
||||
int32_t
|
||||
nsScreen::GetPixelDepth(ErrorResult& aRv)
|
||||
{
|
||||
@@ -162,45 +157,33 @@ nsScreen::GetAvailRect(nsRect& aRect)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsScreen::Notify(const hal::ScreenConfiguration& aConfiguration)
|
||||
mozilla::dom::ScreenOrientation*
|
||||
nsScreen::Orientation() const
|
||||
{
|
||||
ScreenOrientationInternal previousOrientation = mOrientationInternal;
|
||||
mOrientationInternal = aConfiguration.orientation();
|
||||
|
||||
NS_ASSERTION(mOrientationInternal == eScreenOrientation_PortraitPrimary ||
|
||||
mOrientationInternal == eScreenOrientation_PortraitSecondary ||
|
||||
mOrientationInternal == eScreenOrientation_LandscapePrimary ||
|
||||
mOrientationInternal == eScreenOrientation_LandscapeSecondary,
|
||||
"Invalid orientation value passed to notify method!");
|
||||
|
||||
if (mOrientationInternal != previousOrientation) {
|
||||
DispatchTrustedEvent(NS_LITERAL_STRING("mozorientationchange"));
|
||||
}
|
||||
return mScreenOrientation;
|
||||
}
|
||||
|
||||
void
|
||||
nsScreen::GetMozOrientation(nsString& aOrientation)
|
||||
nsScreen::GetMozOrientation(nsString& aOrientation) const
|
||||
{
|
||||
if (ShouldResistFingerprinting()) {
|
||||
aOrientation.AssignLiteral("landscape-primary");
|
||||
} else {
|
||||
switch (mOrientationInternal) {
|
||||
case eScreenOrientation_PortraitPrimary:
|
||||
switch (mScreenOrientation->DeviceType()) {
|
||||
case OrientationType::Portrait_primary:
|
||||
aOrientation.AssignLiteral("portrait-primary");
|
||||
break;
|
||||
case eScreenOrientation_PortraitSecondary:
|
||||
case OrientationType::Portrait_secondary:
|
||||
aOrientation.AssignLiteral("portrait-secondary");
|
||||
break;
|
||||
case eScreenOrientation_LandscapePrimary:
|
||||
case OrientationType::Landscape_primary:
|
||||
aOrientation.AssignLiteral("landscape-primary");
|
||||
break;
|
||||
case eScreenOrientation_LandscapeSecondary:
|
||||
case OrientationType::Landscape_secondary:
|
||||
aOrientation.AssignLiteral("landscape-secondary");
|
||||
break;
|
||||
case eScreenOrientation_None:
|
||||
default:
|
||||
MOZ_CRASH("Unacceptable mOrientationInternal value");
|
||||
MOZ_CRASH("Unacceptable screen orientation type.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -214,35 +197,6 @@ nsScreen::GetSlowMozOrientation(nsAString& aOrientation)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsScreen::LockPermission
|
||||
nsScreen::GetLockOrientationPermission() const
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> owner = GetOwner();
|
||||
if (!owner) {
|
||||
return LOCK_DENIED;
|
||||
}
|
||||
|
||||
// Chrome can always lock the screen orientation.
|
||||
nsIDocShell* docShell = owner->GetDocShell();
|
||||
if (docShell && docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
|
||||
return LOCK_ALLOWED;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = owner->GetDoc();
|
||||
if (!doc || doc->Hidden()) {
|
||||
return LOCK_DENIED;
|
||||
}
|
||||
|
||||
// Apps can always lock the screen orientation.
|
||||
if (doc->NodePrincipal()->GetAppStatus() >=
|
||||
nsIPrincipal::APP_STATUS_INSTALLED) {
|
||||
return LOCK_ALLOWED;
|
||||
}
|
||||
|
||||
// Other content must be full-screen in order to lock orientation.
|
||||
return doc->MozFullScreen() ? FULLSCREEN_LOCK_ALLOWED : LOCK_DENIED;
|
||||
}
|
||||
|
||||
bool
|
||||
nsScreen::MozLockOrientation(const nsAString& aOrientation, ErrorResult& aRv)
|
||||
{
|
||||
@@ -287,34 +241,13 @@ nsScreen::MozLockOrientation(const Sequence<nsString>& aOrientations,
|
||||
}
|
||||
}
|
||||
|
||||
switch (GetLockOrientationPermission()) {
|
||||
case LOCK_DENIED:
|
||||
switch (mScreenOrientation->GetLockOrientationPermission(false)) {
|
||||
case ScreenOrientation::LOCK_DENIED:
|
||||
return false;
|
||||
case LOCK_ALLOWED:
|
||||
return hal::LockScreenOrientation(orientation);
|
||||
case FULLSCREEN_LOCK_ALLOWED: {
|
||||
// We need to register a listener so we learn when we leave full-screen
|
||||
// and when we will have to unlock the screen.
|
||||
// This needs to be done before LockScreenOrientation call to make sure
|
||||
// the locking can be unlocked.
|
||||
nsCOMPtr<EventTarget> target = do_QueryInterface(GetOwner()->GetDoc());
|
||||
if (!target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hal::LockScreenOrientation(orientation)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We are fullscreen and lock has been accepted.
|
||||
if (!mEventListener) {
|
||||
mEventListener = new FullScreenEventListener();
|
||||
}
|
||||
|
||||
aRv = target->AddSystemEventListener(NS_LITERAL_STRING("mozfullscreenchange"),
|
||||
mEventListener, /* useCapture = */ true);
|
||||
return true;
|
||||
}
|
||||
case ScreenOrientation::LOCK_ALLOWED:
|
||||
return mScreenOrientation->LockDeviceOrientation(orientation, false, aRv);
|
||||
case ScreenOrientation::FULLSCREEN_LOCK_ALLOWED:
|
||||
return mScreenOrientation->LockDeviceOrientation(orientation, true, aRv);
|
||||
}
|
||||
|
||||
// This is only for compilers that don't understand that the previous switch
|
||||
@@ -325,20 +258,7 @@ nsScreen::MozLockOrientation(const Sequence<nsString>& aOrientations,
|
||||
void
|
||||
nsScreen::MozUnlockOrientation()
|
||||
{
|
||||
hal::UnlockScreenOrientation();
|
||||
|
||||
if (!mEventListener) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove event listener in case of fullscreen lock.
|
||||
nsCOMPtr<EventTarget> target = do_QueryInterface(GetOwner()->GetDoc());
|
||||
if (target) {
|
||||
target->RemoveSystemEventListener(NS_LITERAL_STRING("mozfullscreenchange"),
|
||||
mEventListener, /* useCapture */ true);
|
||||
}
|
||||
|
||||
mEventListener = nullptr;
|
||||
mScreenOrientation->UnlockDeviceOrientation();
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -361,39 +281,6 @@ nsScreen::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
return ScreenBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsScreen::FullScreenEventListener, nsIDOMEventListener)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScreen::FullScreenEventListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsAutoString eventType;
|
||||
aEvent->GetType(eventType);
|
||||
|
||||
MOZ_ASSERT(eventType.EqualsLiteral("mozfullscreenchange"));
|
||||
#endif
|
||||
|
||||
nsCOMPtr<EventTarget> target = aEvent->InternalDOMEvent()->GetCurrentTarget();
|
||||
MOZ_ASSERT(target);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(target);
|
||||
MOZ_ASSERT(doc);
|
||||
|
||||
// We have to make sure that the event we got is the event sent when
|
||||
// fullscreen is disabled because we could get one when fullscreen
|
||||
// got enabled if the lock call is done at the same moment.
|
||||
if (doc->MozFullScreen()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
target->RemoveSystemEventListener(NS_LITERAL_STRING("mozfullscreenchange"),
|
||||
this, true);
|
||||
|
||||
hal::UnlockScreenOrientation();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsScreen::GetWindowInnerRect(nsRect& aRect)
|
||||
{
|
||||
|
||||
+5
-25
@@ -10,7 +10,6 @@
|
||||
#include "mozilla/dom/ScreenOrientation.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/HalScreenConfiguration.h"
|
||||
#include "nsIDOMScreen.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsRect.h"
|
||||
@@ -20,7 +19,6 @@ class nsDeviceContext;
|
||||
// Script "screen" object
|
||||
class nsScreen : public mozilla::DOMEventTargetHelper
|
||||
, public nsIDOMScreen
|
||||
, public mozilla::hal::ScreenConfigurationObserver
|
||||
{
|
||||
typedef mozilla::ErrorResult ErrorResult;
|
||||
public:
|
||||
@@ -28,6 +26,7 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOMSCREEN
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsScreen, mozilla::DOMEventTargetHelper)
|
||||
NS_REALLY_FORWARD_NSIDOMEVENTTARGET(mozilla::DOMEventTargetHelper)
|
||||
|
||||
nsPIDOMWindow* GetParentObject() const
|
||||
@@ -115,7 +114,8 @@ public:
|
||||
return rect.height;
|
||||
}
|
||||
|
||||
void GetMozOrientation(nsString& aOrientation);
|
||||
// Deprecated
|
||||
void GetMozOrientation(nsString& aOrientation) const;
|
||||
|
||||
IMPL_EVENT_HANDLER(mozorientationchange)
|
||||
|
||||
@@ -125,7 +125,7 @@ public:
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
void Notify(const mozilla::hal::ScreenConfiguration& aConfiguration) override;
|
||||
mozilla::dom::ScreenOrientation* Orientation() const;
|
||||
|
||||
protected:
|
||||
nsDeviceContext* GetDeviceContext();
|
||||
@@ -133,35 +133,15 @@ protected:
|
||||
nsresult GetAvailRect(nsRect& aRect);
|
||||
nsresult GetWindowInnerRect(nsRect& aRect);
|
||||
|
||||
mozilla::dom::ScreenOrientationInternal mOrientationInternal;
|
||||
|
||||
private:
|
||||
class FullScreenEventListener final : public nsIDOMEventListener
|
||||
{
|
||||
~FullScreenEventListener() {}
|
||||
public:
|
||||
FullScreenEventListener() {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
};
|
||||
|
||||
explicit nsScreen(nsPIDOMWindow* aWindow);
|
||||
virtual ~nsScreen();
|
||||
|
||||
enum LockPermission {
|
||||
LOCK_DENIED,
|
||||
FULLSCREEN_LOCK_ALLOWED,
|
||||
LOCK_ALLOWED
|
||||
};
|
||||
|
||||
LockPermission GetLockOrientationPermission() const;
|
||||
|
||||
bool IsDeviceSizePageSize();
|
||||
|
||||
bool ShouldResistFingerprinting() const;
|
||||
|
||||
nsRefPtr<FullScreenEventListener> mEventListener;
|
||||
nsRefPtr<mozilla::dom::ScreenOrientation> mScreenOrientation;
|
||||
};
|
||||
|
||||
#endif /* nsScreen_h___ */
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script src="orientationcommon.js"></script>
|
||||
<script>
|
||||
window.addEventListener("message", function(event) {
|
||||
var p = specialPowersLock(event.data);
|
||||
p.then(function() {
|
||||
event.source.postMessage("success", "*");
|
||||
}).catch(function(err) {
|
||||
event.source.postMessage("error", "*");
|
||||
});
|
||||
}, false);
|
||||
</script>
|
||||
@@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<script>
|
||||
var recordedOrientations = [];
|
||||
|
||||
screen.orientation.onchange = function() {
|
||||
recordedOrientations.push(screen.orientation.type);
|
||||
};
|
||||
|
||||
window.addEventListener("message", function(event) {
|
||||
if (event.data == "report") {
|
||||
event.source.postMessage(recordedOrientations, "*");
|
||||
}
|
||||
}, false);
|
||||
</script>
|
||||
@@ -179,11 +179,13 @@ support-files =
|
||||
file_htmlserializer_2_latin1.html
|
||||
file_htmlserializer_ipv6.html
|
||||
file_htmlserializer_ipv6_out.html
|
||||
file_lock_orientation.html
|
||||
file_mozfiledataurl_audio.ogg
|
||||
file_mozfiledataurl_doc.html
|
||||
file_mozfiledataurl_img.jpg
|
||||
file_mozfiledataurl_inner.html
|
||||
file_mozfiledataurl_text.txt
|
||||
file_record_orientation.html
|
||||
file_restrictedEventSource.sjs
|
||||
file_simplecontentpolicy.js
|
||||
file_websocket_basic_wsh.py
|
||||
@@ -222,6 +224,7 @@ support-files =
|
||||
invalid_accesscontrol.resource
|
||||
invalid_accesscontrol.resource^headers^
|
||||
mutationobserver_dialog.html
|
||||
orientationcommon.js
|
||||
progressserver.sjs
|
||||
responseIdentical.sjs
|
||||
script-1_bug597345.sjs
|
||||
@@ -304,6 +307,14 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Fails on b2g-desktop, track
|
||||
[test_pluginAudioNotification.html]
|
||||
skip-if = (buildapp == 'b2g' || buildapp == 'mulet' || toolkit == 'android') # Plugins don't work on Android and/or B2G/Mulet
|
||||
[test_screen_orientation.html]
|
||||
[test_orientation_alternate.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_orientation_frame.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_orientation_frame_lock.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_orientation_sandbox_no_lock.html]
|
||||
skip-if = toolkit != 'gonk'
|
||||
[test_settimeout_extra_arguments.html]
|
||||
[test_settimeout_inner.html]
|
||||
[test_setting_opener.html]
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
function specialPowersLock(orientation) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [ ["dom.screenorientation.testing.non_fullscreen_lock_allow", true] ]
|
||||
}, function() {
|
||||
var p = screen.orientation.lock(orientation);
|
||||
resolve(p);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function specialPowersUnlock() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
'set': [ ["dom.screenorientation.testing.non_fullscreen_lock_allow", true] ]
|
||||
}, function() {
|
||||
screen.orientation.unlock();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for ScreenOrientation API</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="orientationcommon.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var originalOrientation = screen.orientation.type;
|
||||
var alternateOrientation = originalOrientation == "portrait-primary" ?
|
||||
"landscape-primary" : "portrait-primary";
|
||||
var p = specialPowersLock(alternateOrientation);
|
||||
p.then(function() {
|
||||
t.step(function() { assert_equals(screen.orientation.type, alternateOrientation); });
|
||||
return specialPowersLock(originalOrientation);
|
||||
}).then(function() {
|
||||
t.step(function() { assert_equals(screen.orientation.type, originalOrientation); });
|
||||
return specialPowersUnlock();
|
||||
}).then(function() {
|
||||
t.done();
|
||||
}).catch(t.step_func(function(err) {
|
||||
assert_unreached("Error setting orientation: " + err);
|
||||
t.done();
|
||||
}));
|
||||
}, "Test locking and unlocking orientation.");
|
||||
</script>
|
||||
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for ScreenOrientation API</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="orientationcommon.js"></script>
|
||||
<div id="log"></div>
|
||||
<iframe id="frame"></iframe>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var originalOrientation = screen.orientation.type;
|
||||
var alternateOrientation = originalOrientation == "portrait-primary" ?
|
||||
"landscape-primary" : "portrait-primary";
|
||||
|
||||
window.addEventListener("message", function(event) {
|
||||
t.step(function() { assert_array_equals(event.data, [alternateOrientation, originalOrientation]); });
|
||||
t.done();
|
||||
}, false);
|
||||
|
||||
var frame = document.getElementById("frame");
|
||||
frame.src = "file_record_orientation.html";
|
||||
|
||||
frame.onload = function() {
|
||||
var p = specialPowersLock(alternateOrientation);
|
||||
p.then(function() {
|
||||
return specialPowersLock(originalOrientation);
|
||||
}).then(function() {
|
||||
return specialPowersUnlock();
|
||||
}).then(function() {
|
||||
frame.contentWindow.postMessage("report", "*");
|
||||
}).catch(t.step_func(function(err) {
|
||||
assert_unreached("Error setting orientation: " + err);
|
||||
t.done();
|
||||
}));
|
||||
};
|
||||
}, "Test orientation change event in frame.");
|
||||
</script>
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for ScreenOrientation API</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="orientationcommon.js"></script>
|
||||
<div id="log"></div>
|
||||
<iframe sandbox="allow-scripts allow-orientation-lock" id="frame"></iframe>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var originalOrientation = screen.orientation.type;
|
||||
var alternateOrientation = originalOrientation == "portrait-primary" ?
|
||||
"landscape-primary" : "portrait-primary";
|
||||
|
||||
var orientationChanges = [];
|
||||
window.screen.orientation.onchange = function() {
|
||||
orientationChanges.push(screen.orientation.type);
|
||||
};
|
||||
|
||||
window.addEventListener("message", function(event) {
|
||||
t.step(function() {
|
||||
assert_equals(event.data, "success");
|
||||
assert_array_equals(orientationChanges, [ alternateOrientation ]);
|
||||
});
|
||||
|
||||
// Return the orientation to its original settings.
|
||||
var p = specialPowersLock(originalOrientation);
|
||||
p.then(function() {
|
||||
return specialPowersUnlock();
|
||||
}).then(function() {
|
||||
t.done();
|
||||
}).catch(t.step_func(function(err) {
|
||||
assert_unreached("Error setting orientation: " + err);
|
||||
t.done();
|
||||
}));
|
||||
}, false);
|
||||
|
||||
var frame = document.getElementById("frame");
|
||||
frame.src = "http://example.com/tests/dom/base/test/file_lock_orientation.html";
|
||||
|
||||
frame.onload = function() {
|
||||
assert_array_equals(orientationChanges, []);
|
||||
frame.contentWindow.postMessage(alternateOrientation, "*");
|
||||
};
|
||||
}, "Test orientation lock from within a frame with sandbox permission.");
|
||||
</script>
|
||||
@@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for ScreenOrientation API</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="orientationcommon.js"></script>
|
||||
<div id="log"></div>
|
||||
<iframe sandbox="allow-scripts" id="frame"></iframe>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var originalOrientation = screen.orientation.type;
|
||||
var alternateOrientation = originalOrientation == "portrait-primary" ?
|
||||
"landscape-primary" : "portrait-primary";
|
||||
|
||||
var orientationChanges = [];
|
||||
window.screen.orientation.onchange = function() {
|
||||
orientationChanges.push(screen.orientation.type);
|
||||
};
|
||||
|
||||
window.addEventListener("message", function(event) {
|
||||
t.step(function() {
|
||||
assert_equals(event.data, "error");
|
||||
assert_array_equals(orientationChanges, []);
|
||||
t.done();
|
||||
});
|
||||
}, false);
|
||||
|
||||
var frame = document.getElementById("frame");
|
||||
frame.src = "http://example.com/tests/dom/base/test/file_lock_orientation.html";
|
||||
|
||||
frame.onload = function() {
|
||||
assert_array_equals(orientationChanges, []);
|
||||
frame.contentWindow.postMessage(alternateOrientation, "*");
|
||||
};
|
||||
}, "Test orientation lock from within a frame without sandbox permission.");
|
||||
</script>
|
||||
@@ -18,6 +18,8 @@ struct JSContext;
|
||||
struct JSStructuredCloneReader;
|
||||
struct JSStructuredCloneWriter;
|
||||
|
||||
class nsIGlobalObject;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ErrorResult;
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
class nsISmsService;
|
||||
class nsIDOMMozSmsMessage;
|
||||
class nsIDOMMozMmsMessage;
|
||||
class Promise;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class Promise;
|
||||
class DOMRequest;
|
||||
class DOMCursor;
|
||||
struct MmsParameters;
|
||||
|
||||
@@ -965,6 +965,8 @@ var interfaceNamesInGlobalScope =
|
||||
"RTCStatsReport",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"Screen",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"ScreenOrientation",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
"ScriptProcessorNode",
|
||||
// IMPORTANT: Do not change this list without review from a DOM peer!
|
||||
|
||||
@@ -29,6 +29,7 @@ interface Screen : EventTarget {
|
||||
readonly attribute long availLeft;
|
||||
|
||||
/**
|
||||
* DEPRECATED, use ScreenOrientation API instead.
|
||||
* Returns the current screen orientation.
|
||||
* Can be: landscape-primary, landscape-secondary,
|
||||
* portrait-primary or portrait-secondary.
|
||||
@@ -38,6 +39,7 @@ interface Screen : EventTarget {
|
||||
attribute EventHandler onmozorientationchange;
|
||||
|
||||
/**
|
||||
* DEPRECATED, use ScreenOrientation API instead.
|
||||
* Lock screen orientation to the specified type.
|
||||
*/
|
||||
[Throws, UnsafeInPrerendering]
|
||||
@@ -46,8 +48,14 @@ interface Screen : EventTarget {
|
||||
boolean mozLockOrientation(sequence<DOMString> orientation);
|
||||
|
||||
/**
|
||||
* DEPRECATED, use ScreenOrientation API instead.
|
||||
* Unlock the screen orientation.
|
||||
*/
|
||||
[UnsafeInPrerendering]
|
||||
void mozUnlockOrientation();
|
||||
};
|
||||
|
||||
// https://w3c.github.io/screen-orientation
|
||||
partial interface Screen {
|
||||
readonly attribute ScreenOrientation orientation;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/* -*- 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/.
|
||||
*
|
||||
* The origin of this IDL file is
|
||||
* https://w3c.github.io/screen-orientation
|
||||
*
|
||||
* Copyright © 2014 W3C® (MIT, ERCIM, Keio, Beihang), All Rights
|
||||
* Reserved. W3C liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
enum OrientationType {
|
||||
"portrait-primary",
|
||||
"portrait-secondary",
|
||||
"landscape-primary",
|
||||
"landscape-secondary"
|
||||
};
|
||||
|
||||
enum OrientationLockType {
|
||||
"any",
|
||||
"natural",
|
||||
"landscape",
|
||||
"portrait",
|
||||
"portrait-primary",
|
||||
"portrait-secondary",
|
||||
"landscape-primary",
|
||||
"landscape-secondary"
|
||||
};
|
||||
|
||||
[UnsafeInPrerendering]
|
||||
interface ScreenOrientation : EventTarget {
|
||||
[Throws]
|
||||
Promise<void> lock(OrientationLockType orientation);
|
||||
[Throws]
|
||||
void unlock();
|
||||
[Throws]
|
||||
readonly attribute OrientationType type;
|
||||
[Throws]
|
||||
readonly attribute unsigned short angle;
|
||||
attribute EventHandler onchange;
|
||||
};
|
||||
@@ -385,6 +385,7 @@ WEBIDL_FILES = [
|
||||
'RGBColor.webidl',
|
||||
'RTCStatsReport.webidl',
|
||||
'Screen.webidl',
|
||||
'ScreenOrientation.webidl',
|
||||
'ScriptProcessorNode.webidl',
|
||||
'ScrollAreaEvent.webidl',
|
||||
'ScrollBoxObject.webidl',
|
||||
|
||||
@@ -52,11 +52,6 @@ ServiceWorker::ServiceWorker(nsPIDOMWindow* aWindow,
|
||||
MOZ_ASSERT(aInfo);
|
||||
MOZ_ASSERT(mSharedWorker);
|
||||
|
||||
if (aWindow) {
|
||||
mDocument = aWindow->GetExtantDoc();
|
||||
mWindow = aWindow->GetOuterWindow();
|
||||
}
|
||||
|
||||
// This will update our state too.
|
||||
mInfo->AppendWorker(this);
|
||||
}
|
||||
@@ -74,7 +69,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorker)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorker, DOMEventTargetHelper,
|
||||
mSharedWorker, mDocument, mWindow)
|
||||
mSharedWorker)
|
||||
|
||||
JSObject*
|
||||
ServiceWorker::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
@@ -103,12 +98,9 @@ ServiceWorker::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mDocument && mWindow,
|
||||
"Cannot call PostMessage on a ServiceWorker object that doesn't "
|
||||
"have a window");
|
||||
|
||||
nsAutoPtr<ServiceWorkerClientInfo> clientInfo(
|
||||
new ServiceWorkerClientInfo(mDocument, mWindow));
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(GetParentObject());
|
||||
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
|
||||
nsAutoPtr<ServiceWorkerClientInfo> clientInfo(new ServiceWorkerClientInfo(doc));
|
||||
|
||||
workerPrivate->PostMessageToServiceWorker(aCx, aMessage, aTransferable,
|
||||
clientInfo, aRv);
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/ServiceWorkerBinding.h" // For ServiceWorkerState.
|
||||
|
||||
class nsIDocument;
|
||||
class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
@@ -92,10 +91,6 @@ private:
|
||||
// can be released and recreated as required rather than re-implement some of
|
||||
// the SharedWorker logic.
|
||||
nsRefPtr<SharedWorker> mSharedWorker;
|
||||
// We need to keep the document and window alive for PostMessage to be able
|
||||
// to access them.
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
};
|
||||
|
||||
} // namespace workers
|
||||
|
||||
@@ -29,8 +29,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServiceWorkerClient)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
ServiceWorkerClientInfo::ServiceWorkerClientInfo(nsIDocument* aDoc,
|
||||
nsPIDOMWindow* aWindow)
|
||||
ServiceWorkerClientInfo::ServiceWorkerClientInfo(nsIDocument* aDoc)
|
||||
: mWindowId(0)
|
||||
{
|
||||
MOZ_ASSERT(aDoc);
|
||||
@@ -55,7 +54,7 @@ ServiceWorkerClientInfo::ServiceWorkerClientInfo(nsIDocument* aDoc,
|
||||
NS_WARNING("Failed to get focus information.");
|
||||
}
|
||||
|
||||
nsRefPtr<nsGlobalWindow> outerWindow = static_cast<nsGlobalWindow*>(aWindow);
|
||||
nsRefPtr<nsGlobalWindow> outerWindow = static_cast<nsGlobalWindow*>(aDoc->GetWindow());
|
||||
MOZ_ASSERT(outerWindow);
|
||||
if (!outerWindow->IsTopLevelWindow()) {
|
||||
mFrameType = FrameType::Nested;
|
||||
@@ -135,7 +134,7 @@ private:
|
||||
|
||||
JS::Rooted<JS::Value> messageData(aCx);
|
||||
if (!mBuffer.read(aCx, &messageData,
|
||||
WorkerStructuredCloneCallbacks(true), &closure)) {
|
||||
WorkerStructuredCloneCallbacks(), &closure)) {
|
||||
xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
@@ -195,7 +194,7 @@ ServiceWorkerClient::PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
transferable.setObject(*array);
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks = WorkerStructuredCloneCallbacks(false);
|
||||
const JSStructuredCloneCallbacks* callbacks = WorkerStructuredCloneCallbacks();
|
||||
|
||||
WorkerStructuredCloneClosure closure;
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "mozilla/dom/ClientBinding.h"
|
||||
|
||||
class nsIDocument;
|
||||
class nsPIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@@ -32,7 +31,7 @@ class ServiceWorkerClientInfo final
|
||||
friend class ServiceWorkerWindowClient;
|
||||
|
||||
public:
|
||||
ServiceWorkerClientInfo(nsIDocument* aDoc, nsPIDOMWindow* aWindow);
|
||||
explicit ServiceWorkerClientInfo(nsIDocument* aDoc);
|
||||
|
||||
private:
|
||||
nsString mClientId;
|
||||
|
||||
@@ -3876,7 +3876,7 @@ ServiceWorkerManager::DispatchFetchEvent(const OriginAttributes& aOriginAttribut
|
||||
MOZ_ASSERT(aDoc);
|
||||
aRv = GetDocumentController(aDoc->GetInnerWindow(), failRunnable,
|
||||
getter_AddRefs(serviceWorker));
|
||||
clientInfo = new ServiceWorkerClientInfo(aDoc, aDoc->GetWindow());
|
||||
clientInfo = new ServiceWorkerClientInfo(aDoc);
|
||||
} else {
|
||||
nsCOMPtr<nsIChannel> internalChannel;
|
||||
aRv = aChannel->GetChannel(getter_AddRefs(internalChannel));
|
||||
@@ -4261,7 +4261,7 @@ EnumControlledDocuments(nsISupports* aKey,
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
ServiceWorkerClientInfo clientInfo(document, document->GetWindow());
|
||||
ServiceWorkerClientInfo clientInfo(document);
|
||||
data->mDocuments.AppendElement(clientInfo);
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
|
||||
@@ -91,9 +91,14 @@ public:
|
||||
UniquePtr<ServiceWorkerClientInfo> clientInfo;
|
||||
|
||||
if (window) {
|
||||
nsContentUtils::DispatchChromeEvent(window->GetExtantDoc(), window->GetOuterWindow(), NS_LITERAL_STRING("DOMServiceWorkerFocusClient"), true, true);
|
||||
clientInfo.reset(new ServiceWorkerClientInfo(window->GetDocument(),
|
||||
window->GetOuterWindow()));
|
||||
nsCOMPtr<nsIDocument> doc = window->GetDocument();
|
||||
if (doc) {
|
||||
nsContentUtils::DispatchChromeEvent(doc,
|
||||
window->GetOuterWindow(),
|
||||
NS_LITERAL_STRING("DOMServiceWorkerFocusClient"),
|
||||
true, true);
|
||||
clientInfo.reset(new ServiceWorkerClientInfo(doc));
|
||||
}
|
||||
}
|
||||
|
||||
DispatchResult(Move(clientInfo));
|
||||
|
||||
+46
-277
@@ -406,8 +406,7 @@ EnsureBlobForBackgroundManager(BlobImpl* aBlobImpl,
|
||||
|
||||
already_AddRefed<Blob>
|
||||
ReadBlobOrFileNoWrap(JSContext* aCx,
|
||||
JSStructuredCloneReader* aReader,
|
||||
bool aIsMainThread)
|
||||
JSStructuredCloneReader* aReader)
|
||||
{
|
||||
MOZ_ASSERT(aCx);
|
||||
MOZ_ASSERT(aReader);
|
||||
@@ -426,14 +425,11 @@ ReadBlobOrFileNoWrap(JSContext* aCx,
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
nsCOMPtr<nsISupports> parent;
|
||||
if (aIsMainThread) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> scriptGlobal =
|
||||
nsJSUtils::GetStaticScriptGlobal(JS::CurrentGlobalOrNull(aCx));
|
||||
parent = do_QueryInterface(scriptGlobal);
|
||||
} else {
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
@@ -450,10 +446,9 @@ ReadBlobOrFileNoWrap(JSContext* aCx,
|
||||
void
|
||||
ReadBlobOrFile(JSContext* aCx,
|
||||
JSStructuredCloneReader* aReader,
|
||||
bool aIsMainThread,
|
||||
JS::MutableHandle<JSObject*> aBlobOrFile)
|
||||
{
|
||||
nsRefPtr<Blob> blob = ReadBlobOrFileNoWrap(aCx, aReader, aIsMainThread);
|
||||
nsRefPtr<Blob> blob = ReadBlobOrFileNoWrap(aCx, aReader);
|
||||
aBlobOrFile.set(blob->WrapObject(aCx, nullptr));
|
||||
}
|
||||
|
||||
@@ -461,7 +456,6 @@ ReadBlobOrFile(JSContext* aCx,
|
||||
void
|
||||
ReadFormData(JSContext* aCx,
|
||||
JSStructuredCloneReader* aReader,
|
||||
bool aIsMainThread,
|
||||
uint32_t aCount,
|
||||
JS::MutableHandle<JSObject*> aFormData)
|
||||
{
|
||||
@@ -470,8 +464,7 @@ ReadFormData(JSContext* aCx,
|
||||
MOZ_ASSERT(!aFormData);
|
||||
|
||||
nsCOMPtr<nsISupports> parent;
|
||||
if (aIsMainThread) {
|
||||
AssertIsOnMainThread();
|
||||
if (NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIScriptGlobalObject> scriptGlobal =
|
||||
nsJSUtils::GetStaticScriptGlobal(JS::CurrentGlobalOrNull(aCx));
|
||||
parent = do_QueryInterface(scriptGlobal);
|
||||
@@ -502,7 +495,7 @@ ReadFormData(JSContext* aCx,
|
||||
if (isFile) {
|
||||
// Read out the tag since the blob reader isn't expecting it.
|
||||
MOZ_ALWAYS_TRUE(JS_ReadUint32Pair(aReader, &dummy, &dummy));
|
||||
nsRefPtr<Blob> blob = ReadBlobOrFileNoWrap(aCx, aReader, aIsMainThread);
|
||||
nsRefPtr<Blob> blob = ReadBlobOrFileNoWrap(aCx, aReader);
|
||||
MOZ_ASSERT(blob);
|
||||
formData->Append(name, *blob, thirdArg);
|
||||
} else {
|
||||
@@ -516,28 +509,29 @@ ReadFormData(JSContext* aCx,
|
||||
}
|
||||
|
||||
bool
|
||||
WriteBlobOrFile(JSContext* aCx,
|
||||
JSStructuredCloneWriter* aWriter,
|
||||
BlobImpl* aBlobOrBlobImpl,
|
||||
WriteBlobOrFile(JSStructuredCloneWriter* aWriter,
|
||||
BlobImpl* aBlobImpl,
|
||||
WorkerStructuredCloneClosure& aClosure)
|
||||
{
|
||||
MOZ_ASSERT(aCx);
|
||||
MOZ_ASSERT(aWriter);
|
||||
MOZ_ASSERT(aBlobOrBlobImpl);
|
||||
MOZ_ASSERT(aBlobImpl);
|
||||
|
||||
nsRefPtr<BlobImpl> blobImpl = EnsureBlobForBackgroundManager(aBlobOrBlobImpl);
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
aBlobOrBlobImpl = blobImpl;
|
||||
|
||||
if (NS_WARN_IF(!JS_WriteUint32Pair(aWriter, DOMWORKER_SCTAG_BLOB, 0)) ||
|
||||
NS_WARN_IF(!JS_WriteBytes(aWriter,
|
||||
&aBlobOrBlobImpl,
|
||||
sizeof(aBlobOrBlobImpl)))) {
|
||||
if (!aBlobImpl->MayBeClonedToOtherThreads()) {
|
||||
NS_WARNING("Not all the blob implementations can be sent between threads.");
|
||||
return false;
|
||||
}
|
||||
|
||||
aClosure.mClonedObjects.AppendElement(aBlobOrBlobImpl);
|
||||
nsRefPtr<BlobImpl> blobImpl = EnsureBlobForBackgroundManager(aBlobImpl);
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
aBlobImpl = blobImpl;
|
||||
|
||||
if (NS_WARN_IF(!JS_WriteUint32Pair(aWriter, DOMWORKER_SCTAG_BLOB, 0)) ||
|
||||
NS_WARN_IF(!JS_WriteBytes(aWriter, &aBlobImpl, sizeof(aBlobImpl)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aClosure.mClonedObjects.AppendElement(aBlobImpl);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -565,7 +559,8 @@ WriteFormData(JSContext* aCx,
|
||||
return false;
|
||||
}
|
||||
|
||||
class MOZ_STACK_CLASS Closure {
|
||||
class MOZ_STACK_CLASS Closure final
|
||||
{
|
||||
JSContext* mCx;
|
||||
JSStructuredCloneWriter* mWriter;
|
||||
WorkerStructuredCloneClosure& mClones;
|
||||
@@ -590,7 +585,8 @@ WriteFormData(JSContext* aCx,
|
||||
}
|
||||
|
||||
if (isFile) {
|
||||
if (!WriteBlobOrFile(closure->mCx, closure->mWriter, aFile->Impl(), closure->mClones)) {
|
||||
if (!WriteBlobOrFile(closure->mWriter, aFile->Impl(),
|
||||
closure->mClones)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
@@ -613,27 +609,27 @@ struct WorkerStructuredCloneCallbacks
|
||||
Read(JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag,
|
||||
uint32_t aData, void* aClosure)
|
||||
{
|
||||
JS::Rooted<JSObject*> result(aCx);
|
||||
|
||||
// See if object is a nsIDOMBlob pointer.
|
||||
if (aTag == DOMWORKER_SCTAG_BLOB) {
|
||||
MOZ_ASSERT(!aData);
|
||||
|
||||
JS::Rooted<JSObject*> blobOrFile(aCx);
|
||||
ReadBlobOrFile(aCx, aReader, /* aIsMainThread */ false, &blobOrFile);
|
||||
ReadBlobOrFile(aCx, aReader, &blobOrFile);
|
||||
|
||||
return blobOrFile;
|
||||
}
|
||||
|
||||
// See if the object is an ImageData.
|
||||
else if (aTag == SCTAG_DOM_IMAGEDATA) {
|
||||
if (aTag == SCTAG_DOM_IMAGEDATA) {
|
||||
MOZ_ASSERT(!aData);
|
||||
return ReadStructuredCloneImageData(aCx, aReader);
|
||||
}
|
||||
|
||||
// See if the object is a FormData.
|
||||
else if (aTag == DOMWORKER_SCTAG_FORMDATA) {
|
||||
if (aTag == DOMWORKER_SCTAG_FORMDATA) {
|
||||
JS::Rooted<JSObject*> formData(aCx);
|
||||
// aData is the entry count.
|
||||
ReadFormData(aCx, aReader, /* aIsMainThread */ false, aData, &formData);
|
||||
ReadFormData(aCx, aReader, aData, &formData);
|
||||
return formData;
|
||||
}
|
||||
|
||||
@@ -649,8 +645,7 @@ struct WorkerStructuredCloneCallbacks
|
||||
closure->mClonedImages, aData);
|
||||
}
|
||||
|
||||
Error(aCx, 0);
|
||||
return nullptr;
|
||||
return NS_DOMReadStructuredClone(aCx, aReader, aTag, aData, nullptr);
|
||||
}
|
||||
|
||||
static bool
|
||||
@@ -668,7 +663,7 @@ struct WorkerStructuredCloneCallbacks
|
||||
BlobImpl* blobImpl = blob->Impl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
if (WriteBlobOrFile(aCx, aWriter, blobImpl, *closure)) {
|
||||
if (WriteBlobOrFile(aWriter, blobImpl, *closure)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -702,8 +697,7 @@ struct WorkerStructuredCloneCallbacks
|
||||
}
|
||||
}
|
||||
|
||||
Error(aCx, 0);
|
||||
return false;
|
||||
return NS_DOMWriteStructuredClone(aCx, aWriter, aObj, nullptr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -810,198 +804,6 @@ const JSStructuredCloneCallbacks gWorkerStructuredCloneCallbacks = {
|
||||
WorkerStructuredCloneCallbacks::FreeTransfer
|
||||
};
|
||||
|
||||
struct MainThreadWorkerStructuredCloneCallbacks
|
||||
{
|
||||
static JSObject*
|
||||
Read(JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag,
|
||||
uint32_t aData, void* aClosure)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
// See if object is a Blob/File pointer.
|
||||
if (aTag == DOMWORKER_SCTAG_BLOB) {
|
||||
MOZ_ASSERT(!aData);
|
||||
|
||||
JS::Rooted<JSObject*> blobOrFile(aCx);
|
||||
ReadBlobOrFile(aCx, aReader, /* aIsMainThread */ true, &blobOrFile);
|
||||
|
||||
return blobOrFile;
|
||||
}
|
||||
// See if the object is a FormData.
|
||||
else if (aTag == DOMWORKER_SCTAG_FORMDATA) {
|
||||
JS::Rooted<JSObject*> formData(aCx);
|
||||
// aData is the entry count.
|
||||
ReadFormData(aCx, aReader, /* aIsMainThread */ true, aData, &formData);
|
||||
return formData;
|
||||
}
|
||||
|
||||
// See if the object is a ImageBitmap
|
||||
if (aTag == SCTAG_DOM_IMAGEBITMAP) {
|
||||
NS_ASSERTION(aClosure, "Null pointer!");
|
||||
|
||||
// Get the current global object.
|
||||
auto* closure = static_cast<WorkerStructuredCloneClosure*>(aClosure);
|
||||
nsCOMPtr<nsIGlobalObject> parent = do_QueryInterface(closure->mParentWindow);
|
||||
// aData is the index of the cloned image.
|
||||
return ImageBitmap::ReadStructuredClone(aCx, aReader, parent,
|
||||
closure->mClonedImages, aData);
|
||||
}
|
||||
|
||||
JS_ClearPendingException(aCx);
|
||||
return NS_DOMReadStructuredClone(aCx, aReader, aTag, aData, nullptr);
|
||||
}
|
||||
|
||||
static bool
|
||||
Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
|
||||
JS::Handle<JSObject*> aObj, void* aClosure)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
NS_ASSERTION(aClosure, "Null pointer!");
|
||||
|
||||
auto* closure = static_cast<WorkerStructuredCloneClosure*>(aClosure);
|
||||
|
||||
// See if this is a Blob/File object.
|
||||
{
|
||||
nsRefPtr<Blob> blob;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob))) {
|
||||
BlobImpl* blobImpl = blob->Impl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
if (!blobImpl->MayBeClonedToOtherThreads()) {
|
||||
NS_WARNING("Not all the blob implementations can be sent between threads.");
|
||||
} else if (WriteBlobOrFile(aCx, aWriter, blobImpl, *closure)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle imageBitmap cloning
|
||||
{
|
||||
ImageBitmap* imageBitmap = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(ImageBitmap, aObj, imageBitmap))) {
|
||||
return ImageBitmap::WriteStructuredClone(aWriter,
|
||||
closure->mClonedImages,
|
||||
imageBitmap);
|
||||
}
|
||||
}
|
||||
|
||||
JS_ClearPendingException(aCx);
|
||||
return NS_DOMWriteStructuredClone(aCx, aWriter, aObj, nullptr);
|
||||
}
|
||||
|
||||
static void
|
||||
Error(JSContext* aCx, uint32_t aErrorId)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
NS_DOMStructuredCloneError(aCx, aErrorId);
|
||||
}
|
||||
};
|
||||
|
||||
const JSStructuredCloneCallbacks gMainThreadWorkerStructuredCloneCallbacks = {
|
||||
MainThreadWorkerStructuredCloneCallbacks::Read,
|
||||
MainThreadWorkerStructuredCloneCallbacks::Write,
|
||||
MainThreadWorkerStructuredCloneCallbacks::Error,
|
||||
WorkerStructuredCloneCallbacks::ReadTransfer,
|
||||
WorkerStructuredCloneCallbacks::Transfer,
|
||||
WorkerStructuredCloneCallbacks::FreeTransfer
|
||||
};
|
||||
|
||||
struct ChromeWorkerStructuredCloneCallbacks
|
||||
{
|
||||
static JSObject*
|
||||
Read(JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag,
|
||||
uint32_t aData, void* aClosure)
|
||||
{
|
||||
return WorkerStructuredCloneCallbacks::Read(aCx, aReader, aTag, aData,
|
||||
aClosure);
|
||||
}
|
||||
|
||||
static bool
|
||||
Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
|
||||
JS::Handle<JSObject*> aObj, void* aClosure)
|
||||
{
|
||||
return WorkerStructuredCloneCallbacks::Write(aCx, aWriter, aObj, aClosure);
|
||||
}
|
||||
|
||||
static void
|
||||
Error(JSContext* aCx, uint32_t aErrorId)
|
||||
{
|
||||
return WorkerStructuredCloneCallbacks::Error(aCx, aErrorId);
|
||||
}
|
||||
};
|
||||
|
||||
const JSStructuredCloneCallbacks gChromeWorkerStructuredCloneCallbacks = {
|
||||
ChromeWorkerStructuredCloneCallbacks::Read,
|
||||
ChromeWorkerStructuredCloneCallbacks::Write,
|
||||
ChromeWorkerStructuredCloneCallbacks::Error,
|
||||
WorkerStructuredCloneCallbacks::ReadTransfer,
|
||||
WorkerStructuredCloneCallbacks::Transfer,
|
||||
WorkerStructuredCloneCallbacks::FreeTransfer
|
||||
};
|
||||
|
||||
struct MainThreadChromeWorkerStructuredCloneCallbacks
|
||||
{
|
||||
static JSObject*
|
||||
Read(JSContext* aCx, JSStructuredCloneReader* aReader, uint32_t aTag,
|
||||
uint32_t aData, void* aClosure)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
JSObject* clone =
|
||||
MainThreadWorkerStructuredCloneCallbacks::Read(aCx, aReader, aTag, aData,
|
||||
aClosure);
|
||||
if (clone) {
|
||||
return clone;
|
||||
}
|
||||
|
||||
clone =
|
||||
ChromeWorkerStructuredCloneCallbacks::Read(aCx, aReader, aTag, aData,
|
||||
aClosure);
|
||||
if (clone) {
|
||||
return clone;
|
||||
}
|
||||
|
||||
JS_ClearPendingException(aCx);
|
||||
return NS_DOMReadStructuredClone(aCx, aReader, aTag, aData, nullptr);
|
||||
}
|
||||
|
||||
static bool
|
||||
Write(JSContext* aCx, JSStructuredCloneWriter* aWriter,
|
||||
JS::Handle<JSObject*> aObj, void* aClosure)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (MainThreadWorkerStructuredCloneCallbacks::Write(aCx, aWriter, aObj,
|
||||
aClosure) ||
|
||||
ChromeWorkerStructuredCloneCallbacks::Write(aCx, aWriter, aObj,
|
||||
aClosure) ||
|
||||
NS_DOMWriteStructuredClone(aCx, aWriter, aObj, nullptr)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
Error(JSContext* aCx, uint32_t aErrorId)
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
|
||||
NS_DOMStructuredCloneError(aCx, aErrorId);
|
||||
}
|
||||
};
|
||||
|
||||
const JSStructuredCloneCallbacks gMainThreadChromeWorkerStructuredCloneCallbacks = {
|
||||
MainThreadChromeWorkerStructuredCloneCallbacks::Read,
|
||||
MainThreadChromeWorkerStructuredCloneCallbacks::Write,
|
||||
MainThreadChromeWorkerStructuredCloneCallbacks::Error,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
};
|
||||
|
||||
class MainThreadReleaseRunnable final : public nsRunnable
|
||||
{
|
||||
nsTArray<nsCOMPtr<nsISupports>> mDoomed;
|
||||
@@ -1346,7 +1148,7 @@ public:
|
||||
|
||||
JS::Rooted<JS::Value> messageData(aCx);
|
||||
if (!mBuffer.read(aCx, &messageData,
|
||||
workers::WorkerStructuredCloneCallbacks(aIsMainThread),
|
||||
workers::WorkerStructuredCloneCallbacks(),
|
||||
&closure)) {
|
||||
xpc::Throw(aCx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return false;
|
||||
@@ -1356,7 +1158,7 @@ public:
|
||||
nsresult rv =
|
||||
event->InitMessageEvent(NS_LITERAL_STRING("message"),
|
||||
false /* non-bubbling */,
|
||||
true /* cancelable */,
|
||||
false /* non-cancelable */,
|
||||
messageData,
|
||||
EmptyString(),
|
||||
EmptyString(),
|
||||
@@ -3483,26 +3285,6 @@ WorkerPrivateParent<Derived>::PostMessageInternal(
|
||||
}
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks;
|
||||
if (GetParent()) {
|
||||
if (IsChromeWorker()) {
|
||||
callbacks = &gChromeWorkerStructuredCloneCallbacks;
|
||||
}
|
||||
else {
|
||||
callbacks = &gWorkerStructuredCloneCallbacks;
|
||||
}
|
||||
}
|
||||
else {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
if (IsChromeWorker()) {
|
||||
callbacks = &gMainThreadChromeWorkerStructuredCloneCallbacks;
|
||||
}
|
||||
else {
|
||||
callbacks = &gMainThreadWorkerStructuredCloneCallbacks;
|
||||
}
|
||||
}
|
||||
|
||||
JS::Rooted<JS::Value> transferable(aCx, JS::UndefinedValue());
|
||||
if (aTransferable.WasPassed()) {
|
||||
const Sequence<JS::Value>& realTransferable = aTransferable.Value();
|
||||
@@ -3527,7 +3309,8 @@ WorkerPrivateParent<Derived>::PostMessageInternal(
|
||||
WorkerRunnable::WorkerThreadModifyBusyCount,
|
||||
aToMessagePort, aMessagePortSerial);
|
||||
|
||||
if (!runnable->Write(aCx, aMessage, transferable, callbacks)) {
|
||||
if (!runnable->Write(aCx, aMessage, transferable,
|
||||
&gWorkerStructuredCloneCallbacks)) {
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return;
|
||||
}
|
||||
@@ -3577,8 +3360,6 @@ WorkerPrivateParent<Derived>::DispatchMessageEventToMessagePort(
|
||||
AssertIsOnMainThread();
|
||||
|
||||
JSAutoStructuredCloneBuffer buffer(Move(aBuffer));
|
||||
const JSStructuredCloneCallbacks* callbacks =
|
||||
WorkerStructuredCloneCallbacks(true);
|
||||
|
||||
class MOZ_STACK_CLASS AutoCloneBufferCleaner final
|
||||
{
|
||||
@@ -3608,7 +3389,9 @@ WorkerPrivateParent<Derived>::DispatchMessageEventToMessagePort(
|
||||
MOZ_ASSERT(aClosure.mMessagePorts.IsEmpty());
|
||||
closure.mMessagePortIdentifiers.SwapElements(aClosure.mMessagePortIdentifiers);
|
||||
|
||||
AutoCloneBufferCleaner bufferCleaner(buffer, callbacks, closure);
|
||||
AutoCloneBufferCleaner bufferCleaner(buffer,
|
||||
&gWorkerStructuredCloneCallbacks,
|
||||
closure);
|
||||
|
||||
SharedWorker* sharedWorker;
|
||||
if (!mSharedWorkers.Get(aMessagePortSerial, &sharedWorker)) {
|
||||
@@ -3632,7 +3415,7 @@ WorkerPrivateParent<Derived>::DispatchMessageEventToMessagePort(
|
||||
JSContext* cx = jsapi.cx();
|
||||
|
||||
JS::Rooted<JS::Value> data(cx);
|
||||
if (!buffer.read(cx, &data, WorkerStructuredCloneCallbacks(true),
|
||||
if (!buffer.read(cx, &data, &gWorkerStructuredCloneCallbacks,
|
||||
&closure)) {
|
||||
return false;
|
||||
}
|
||||
@@ -6292,17 +6075,13 @@ WorkerPrivate::PostMessageToParentInternal(
|
||||
transferable.setObject(*array);
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks =
|
||||
IsChromeWorker() ?
|
||||
&gChromeWorkerStructuredCloneCallbacks :
|
||||
&gWorkerStructuredCloneCallbacks;
|
||||
|
||||
nsRefPtr<MessageEventRunnable> runnable =
|
||||
new MessageEventRunnable(this,
|
||||
WorkerRunnable::ParentThreadUnchangedBusyCount,
|
||||
aToMessagePort, aMessagePortSerial);
|
||||
|
||||
if (!runnable->Write(aCx, aMessage, transferable, callbacks)) {
|
||||
if (!runnable->Write(aCx, aMessage, transferable,
|
||||
&gWorkerStructuredCloneCallbacks)) {
|
||||
aRv = NS_ERROR_DOM_DATA_CLONE_ERR;
|
||||
return;
|
||||
}
|
||||
@@ -7445,19 +7224,9 @@ GetWorkerCrossThreadDispatcher(JSContext* aCx, JS::Value aWorker)
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks*
|
||||
WorkerStructuredCloneCallbacks(bool aMainRuntime)
|
||||
WorkerStructuredCloneCallbacks()
|
||||
{
|
||||
return aMainRuntime ?
|
||||
&gMainThreadWorkerStructuredCloneCallbacks :
|
||||
&gWorkerStructuredCloneCallbacks;
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks*
|
||||
ChromeWorkerStructuredCloneCallbacks(bool aMainRuntime)
|
||||
{
|
||||
return aMainRuntime ?
|
||||
&gMainThreadChromeWorkerStructuredCloneCallbacks :
|
||||
&gChromeWorkerStructuredCloneCallbacks;
|
||||
return &gWorkerStructuredCloneCallbacks;
|
||||
}
|
||||
|
||||
// Force instantiation.
|
||||
|
||||
@@ -1520,10 +1520,7 @@ enum WorkerStructuredDataType
|
||||
};
|
||||
|
||||
const JSStructuredCloneCallbacks*
|
||||
WorkerStructuredCloneCallbacks(bool aMainRuntime);
|
||||
|
||||
const JSStructuredCloneCallbacks*
|
||||
ChromeWorkerStructuredCloneCallbacks(bool aMainRuntime);
|
||||
WorkerStructuredCloneCallbacks();
|
||||
|
||||
class AutoSyncLoopHolder
|
||||
{
|
||||
|
||||
@@ -1229,9 +1229,7 @@ EventRunnable::PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
if (doClone) {
|
||||
// Anything subject to GC must be cloned.
|
||||
const JSStructuredCloneCallbacks* callbacks =
|
||||
aWorkerPrivate->IsChromeWorker() ?
|
||||
workers::ChromeWorkerStructuredCloneCallbacks(true) :
|
||||
workers::WorkerStructuredCloneCallbacks(true);
|
||||
workers::WorkerStructuredCloneCallbacks();
|
||||
|
||||
WorkerStructuredCloneClosure closure;
|
||||
|
||||
@@ -1344,9 +1342,7 @@ EventRunnable::WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
JSAutoStructuredCloneBuffer responseBuffer(Move(mResponseBuffer));
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks =
|
||||
aWorkerPrivate->IsChromeWorker() ?
|
||||
workers::ChromeWorkerStructuredCloneCallbacks(false) :
|
||||
workers::WorkerStructuredCloneCallbacks(false);
|
||||
workers::WorkerStructuredCloneCallbacks();
|
||||
|
||||
WorkerStructuredCloneClosure closure;
|
||||
closure.mClonedObjects.SwapElements(mResponseClosure.mClonedObjects);
|
||||
@@ -1531,9 +1527,7 @@ SendRunnable::MainThreadRun()
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks =
|
||||
mWorkerPrivate->IsChromeWorker() ?
|
||||
workers::ChromeWorkerStructuredCloneCallbacks(true) :
|
||||
workers::WorkerStructuredCloneCallbacks(true);
|
||||
workers::WorkerStructuredCloneCallbacks();
|
||||
|
||||
JS::Rooted<JS::Value> body(cx);
|
||||
if (mBody.read(cx, &body, callbacks, &mClosure)) {
|
||||
@@ -2178,9 +2172,7 @@ XMLHttpRequest::Send(JS::Handle<JSObject*> aBody, ErrorResult& aRv)
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks =
|
||||
mWorkerPrivate->IsChromeWorker() ?
|
||||
ChromeWorkerStructuredCloneCallbacks(false) :
|
||||
WorkerStructuredCloneCallbacks(false);
|
||||
WorkerStructuredCloneCallbacks();
|
||||
|
||||
WorkerStructuredCloneClosure closure;
|
||||
|
||||
@@ -2224,9 +2216,7 @@ XMLHttpRequest::Send(Blob& aBody, ErrorResult& aRv)
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks =
|
||||
mWorkerPrivate->IsChromeWorker() ?
|
||||
ChromeWorkerStructuredCloneCallbacks(false) :
|
||||
WorkerStructuredCloneCallbacks(false);
|
||||
WorkerStructuredCloneCallbacks();
|
||||
|
||||
WorkerStructuredCloneClosure closure;
|
||||
|
||||
@@ -2262,9 +2252,7 @@ XMLHttpRequest::Send(nsFormData& aBody, ErrorResult& aRv)
|
||||
}
|
||||
|
||||
const JSStructuredCloneCallbacks* callbacks =
|
||||
mWorkerPrivate->IsChromeWorker() ?
|
||||
ChromeWorkerStructuredCloneCallbacks(false) :
|
||||
WorkerStructuredCloneCallbacks(false);
|
||||
WorkerStructuredCloneCallbacks();
|
||||
|
||||
JSAutoStructuredCloneBuffer buffer;
|
||||
WorkerStructuredCloneClosure closure;
|
||||
|
||||
@@ -117,7 +117,7 @@ GetXrayType(JSObject* obj)
|
||||
}
|
||||
|
||||
JSObject*
|
||||
XrayAwareCalleeGlobal(JSObject *fun)
|
||||
XrayAwareCalleeGlobal(JSObject* fun)
|
||||
{
|
||||
MOZ_ASSERT(js::IsFunctionObject(fun));
|
||||
|
||||
@@ -127,17 +127,17 @@ XrayAwareCalleeGlobal(JSObject *fun)
|
||||
}
|
||||
|
||||
// The functions we expect here have the Xray wrapper they're associated with
|
||||
// in their XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT and, in a debug build, their
|
||||
// JSNative in their XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_ASSERT. Assert that
|
||||
// in their XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT and, in a debug build,
|
||||
// themselves in their XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_SELF. Assert that
|
||||
// last bit.
|
||||
MOZ_ASSERT(js::GetFunctionNativeReserved(fun, XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_ASSERT).toPrivate() ==
|
||||
js::GetFunctionObjectNative(fun));
|
||||
MOZ_ASSERT(&js::GetFunctionNativeReserved(fun, XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_SELF).toObject() ==
|
||||
fun);
|
||||
|
||||
Value v =
|
||||
js::GetFunctionNativeReserved(fun, XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT);
|
||||
MOZ_ASSERT(IsXrayWrapper(&v.toObject()));
|
||||
|
||||
JSObject *xrayTarget = js::UncheckedUnwrap(&v.toObject());
|
||||
JSObject* xrayTarget = js::UncheckedUnwrap(&v.toObject());
|
||||
return js::GetGlobalForObjectCrossCompartment(xrayTarget);
|
||||
}
|
||||
|
||||
@@ -269,6 +269,21 @@ ReportWrapperDenial(JSContext* cx, HandleId id, WrapperDenialType type, const ch
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JSXrayTraits::getOwnPropertyFromWrapperIfSafe(JSContext* cx,
|
||||
HandleObject wrapper,
|
||||
HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> outDesc)
|
||||
{
|
||||
MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx));
|
||||
RootedObject target(cx, getTargetObject(wrapper));
|
||||
{
|
||||
JSAutoCompartment ac(cx, target);
|
||||
if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, id, outDesc))
|
||||
return false;
|
||||
}
|
||||
return JS_WrapPropertyDescriptor(cx, outDesc);
|
||||
}
|
||||
|
||||
bool JSXrayTraits::getOwnPropertyFromTargetIfSafe(JSContext* cx,
|
||||
HandleObject target,
|
||||
HandleObject wrapper,
|
||||
@@ -382,12 +397,7 @@ JSXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsWrapper,
|
||||
// "should" look like over Xrays, the underlying object is squishy enough
|
||||
// that it makes sense to just treat them like Objects for Xray purposes.
|
||||
if (key == JSProto_Object || key == JSProto_Array) {
|
||||
{
|
||||
JSAutoCompartment ac(cx, target);
|
||||
if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, id, desc))
|
||||
return false;
|
||||
}
|
||||
return JS_WrapPropertyDescriptor(cx, desc);
|
||||
return getOwnPropertyFromWrapperIfSafe(cx, wrapper, id, desc);
|
||||
} else if (IsTypedArrayKey(key)) {
|
||||
if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
|
||||
JS_ReportError(cx, "Accessing TypedArray data over Xrays is slow, and forbidden "
|
||||
@@ -450,10 +460,8 @@ JSXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsWrapper,
|
||||
return true;
|
||||
}
|
||||
} else if (key == JSProto_RegExp) {
|
||||
if (id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_LASTINDEX)) {
|
||||
JSAutoCompartment ac(cx, target);
|
||||
return getOwnPropertyFromTargetIfSafe(cx, target, wrapper, id, desc);
|
||||
}
|
||||
if (id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_LASTINDEX))
|
||||
return getOwnPropertyFromWrapperIfSafe(cx, wrapper, id, desc);
|
||||
}
|
||||
|
||||
// The rest of this function applies only to prototypes.
|
||||
@@ -499,10 +507,8 @@ JSXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsWrapper,
|
||||
}
|
||||
|
||||
// Handle the 'lastIndex' property for RegExp prototypes.
|
||||
if (key == JSProto_RegExp && id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_LASTINDEX)) {
|
||||
JSAutoCompartment ac(cx, target);
|
||||
return getOwnPropertyFromTargetIfSafe(cx, target, wrapper, id, desc);
|
||||
}
|
||||
if (key == JSProto_RegExp && id == GetRTIdByIndex(cx, XPCJSRuntime::IDX_LASTINDEX))
|
||||
return getOwnPropertyFromWrapperIfSafe(cx, wrapper, id, desc);
|
||||
|
||||
// Grab the JSClass. We require all Xrayable classes to have a ClassSpec.
|
||||
const js::Class* clasp = js::GetObjectClass(target);
|
||||
@@ -588,7 +594,7 @@ JSXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsWrapper,
|
||||
}
|
||||
|
||||
bool
|
||||
JSXrayTraits::delete_(JSContext *cx, HandleObject wrapper, HandleId id, ObjectOpResult &result)
|
||||
JSXrayTraits::delete_(JSContext* cx, HandleObject wrapper, HandleId id, ObjectOpResult& result)
|
||||
{
|
||||
RootedObject holder(cx, ensureHolder(cx, wrapper));
|
||||
|
||||
@@ -611,11 +617,11 @@ JSXrayTraits::delete_(JSContext *cx, HandleObject wrapper, HandleId id, ObjectOp
|
||||
}
|
||||
|
||||
bool
|
||||
JSXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
JSXrayTraits::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> existingDesc,
|
||||
ObjectOpResult &result,
|
||||
bool *defined)
|
||||
ObjectOpResult& result,
|
||||
bool* defined)
|
||||
{
|
||||
*defined = false;
|
||||
RootedObject holder(cx, ensureHolder(cx, wrapper));
|
||||
@@ -1063,7 +1069,7 @@ XrayTraits::cloneExpandoChain(JSContext* cx, HandleObject dst, HandleObject src)
|
||||
// preserved when expandos were originally added to |src|. Assert the
|
||||
// wrapper for |src| has been preserved if it has expandos set.
|
||||
if (oldHead) {
|
||||
nsISupports *identity = mozilla::dom::UnwrapDOMObjectToISupports(src);
|
||||
nsISupports* identity = mozilla::dom::UnwrapDOMObjectToISupports(src);
|
||||
if (identity) {
|
||||
nsWrapperCache* cache = nullptr;
|
||||
CallQueryInterface(identity, &cache);
|
||||
@@ -1244,7 +1250,7 @@ XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext* cx, HandleObject wr
|
||||
if (id != nsXPConnect::GetRuntimeInstance()->GetStringID(XPCJSRuntime::IDX_TO_STRING))
|
||||
return true;
|
||||
|
||||
JSFunction *toString = JS_NewFunction(cx, XrayToString, 0, 0, "toString");
|
||||
JSFunction* toString = JS_NewFunction(cx, XrayToString, 0, 0, "toString");
|
||||
if (!toString)
|
||||
return false;
|
||||
|
||||
@@ -1442,10 +1448,10 @@ XPCWrappedNativeXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsW
|
||||
}
|
||||
|
||||
bool
|
||||
XPCWrappedNativeXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
XPCWrappedNativeXrayTraits::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined)
|
||||
JS::ObjectOpResult& result, bool* defined)
|
||||
{
|
||||
*defined = false;
|
||||
RootedObject holder(cx, singleton.ensureHolder(cx, wrapper));
|
||||
@@ -1602,10 +1608,10 @@ DOMXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsWrapper, Handl
|
||||
}
|
||||
|
||||
bool
|
||||
DOMXrayTraits::defineProperty(JSContext *cx, HandleObject wrapper, HandleId id,
|
||||
DOMXrayTraits::defineProperty(JSContext* cx, HandleObject wrapper, HandleId id,
|
||||
Handle<JSPropertyDescriptor> desc,
|
||||
Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined)
|
||||
JS::ObjectOpResult& result, bool* defined)
|
||||
{
|
||||
// Check for an indexed property on a Window. If that's happening, do
|
||||
// nothing but claim we defined it so it won't get added as an expando.
|
||||
@@ -1685,7 +1691,7 @@ DOMXrayTraits::construct(JSContext* cx, HandleObject wrapper,
|
||||
}
|
||||
|
||||
bool
|
||||
DOMXrayTraits::getPrototype(JSContext *cx, JS::HandleObject wrapper,
|
||||
DOMXrayTraits::getPrototype(JSContext* cx, JS::HandleObject wrapper,
|
||||
JS::HandleObject target,
|
||||
JS::MutableHandleObject protop)
|
||||
{
|
||||
@@ -1816,8 +1822,8 @@ XrayToString(JSContext* cx, unsigned argc, Value* vp)
|
||||
|
||||
template <typename Base, typename Traits>
|
||||
bool
|
||||
XrayWrapper<Base, Traits>::preventExtensions(JSContext *cx, HandleObject wrapper,
|
||||
ObjectOpResult &result) const
|
||||
XrayWrapper<Base, Traits>::preventExtensions(JSContext* cx, HandleObject wrapper,
|
||||
ObjectOpResult& result) const
|
||||
{
|
||||
// Xray wrappers are supposed to provide a clean view of the target
|
||||
// reflector, hiding any modifications by script in the target scope. So
|
||||
@@ -1957,7 +1963,7 @@ XrayWrapper<Base, Traits>::getOwnPropertyDescriptor(JSContext* cx, HandleObject
|
||||
// to the content object. This is ok, because the the expando object is only
|
||||
// ever accessed by code across the compartment boundary.
|
||||
static bool
|
||||
RecreateLostWaivers(JSContext *cx, const JSPropertyDescriptor *orig,
|
||||
RecreateLostWaivers(JSContext* cx, const JSPropertyDescriptor* orig,
|
||||
MutableHandle<JSPropertyDescriptor> wrapped)
|
||||
{
|
||||
// Compute whether the original objects were waived, and implicitly, whether
|
||||
@@ -2001,9 +2007,9 @@ RecreateLostWaivers(JSContext *cx, const JSPropertyDescriptor *orig,
|
||||
|
||||
template <typename Base, typename Traits>
|
||||
bool
|
||||
XrayWrapper<Base, Traits>::defineProperty(JSContext *cx, HandleObject wrapper,
|
||||
XrayWrapper<Base, Traits>::defineProperty(JSContext* cx, HandleObject wrapper,
|
||||
HandleId id, Handle<JSPropertyDescriptor> desc,
|
||||
ObjectOpResult &result) const
|
||||
ObjectOpResult& result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, wrapper, id, BaseProxyHandler::SET);
|
||||
|
||||
@@ -2075,7 +2081,7 @@ XrayWrapper<Base, Traits>::ownPropertyKeys(JSContext* cx, HandleObject wrapper,
|
||||
template <typename Base, typename Traits>
|
||||
bool
|
||||
XrayWrapper<Base, Traits>::delete_(JSContext* cx, HandleObject wrapper,
|
||||
HandleId id, ObjectOpResult &result) const
|
||||
HandleId id, ObjectOpResult& result) const
|
||||
{
|
||||
assertEnteredPolicy(cx, wrapper, id, BaseProxyHandler::SET);
|
||||
|
||||
@@ -2200,7 +2206,7 @@ XrayWrapper<Base, Traits>::defaultValue(JSContext* cx, HandleObject wrapper,
|
||||
|
||||
template <typename Base, typename Traits>
|
||||
bool
|
||||
XrayWrapper<Base, Traits>::getPrototype(JSContext *cx, JS::HandleObject wrapper,
|
||||
XrayWrapper<Base, Traits>::getPrototype(JSContext* cx, JS::HandleObject wrapper,
|
||||
JS::MutableHandleObject protop) const
|
||||
{
|
||||
// We really only want this override for non-SecurityWrapper-inheriting
|
||||
@@ -2233,8 +2239,8 @@ XrayWrapper<Base, Traits>::getPrototype(JSContext *cx, JS::HandleObject wrapper,
|
||||
|
||||
template <typename Base, typename Traits>
|
||||
bool
|
||||
XrayWrapper<Base, Traits>::setPrototype(JSContext *cx, JS::HandleObject wrapper,
|
||||
JS::HandleObject proto, JS::ObjectOpResult &result) const
|
||||
XrayWrapper<Base, Traits>::setPrototype(JSContext* cx, JS::HandleObject wrapper,
|
||||
JS::HandleObject proto, JS::ObjectOpResult& result) const
|
||||
{
|
||||
// Do this only for non-SecurityWrapper-inheriting |Base|. See the comment
|
||||
// in getPrototype().
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
// the Xray wrapper they're associated with.
|
||||
#define XRAY_DOM_FUNCTION_PARENT_WRAPPER_SLOT 0
|
||||
// Slot where in debug builds Xray functions for Web IDL methods store
|
||||
// a pointer to their JSNative, just so we can assert that they're the
|
||||
// a pointer to their themselves, just so we can assert that they're the
|
||||
// sort of functions we expect.
|
||||
#define XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_ASSERT 1
|
||||
#define XRAY_DOM_FUNCTION_NATIVE_SLOT_FOR_SELF 1
|
||||
|
||||
// Xray wrappers re-resolve the original native properties on the native
|
||||
// object and always directly access to those properties.
|
||||
@@ -78,8 +78,8 @@ public:
|
||||
JS::HandleObject wrapper, JS::HandleObject holder,
|
||||
JS::HandleId id, JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
||||
bool delete_(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::ObjectOpResult &result) {
|
||||
bool delete_(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::ObjectOpResult& result) {
|
||||
return result.succeed();
|
||||
}
|
||||
|
||||
@@ -132,10 +132,10 @@ public:
|
||||
virtual bool resolveOwnProperty(JSContext* cx, const js::Wrapper& jsWrapper, JS::HandleObject wrapper,
|
||||
JS::HandleObject holder, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) override;
|
||||
bool defineProperty(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
bool defineProperty(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined);
|
||||
JS::ObjectOpResult& result, bool* defined);
|
||||
virtual bool enumerateNames(JSContext* cx, JS::HandleObject wrapper, unsigned flags,
|
||||
JS::AutoIdVector& props);
|
||||
static bool call(JSContext* cx, JS::HandleObject wrapper,
|
||||
@@ -184,22 +184,22 @@ public:
|
||||
virtual bool resolveOwnProperty(JSContext* cx, const js::Wrapper& jsWrapper, JS::HandleObject wrapper,
|
||||
JS::HandleObject holder, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) override;
|
||||
bool defineProperty(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
bool defineProperty(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined);
|
||||
JS::ObjectOpResult& result, bool* defined);
|
||||
virtual bool enumerateNames(JSContext* cx, JS::HandleObject wrapper, unsigned flags,
|
||||
JS::AutoIdVector& props);
|
||||
static bool call(JSContext* cx, JS::HandleObject wrapper,
|
||||
const JS::CallArgs& args, const js::Wrapper& baseInstance);
|
||||
static bool construct(JSContext *cx, JS::HandleObject wrapper,
|
||||
const JS::CallArgs &args, const js::Wrapper& baseInstance);
|
||||
static bool construct(JSContext* cx, JS::HandleObject wrapper,
|
||||
const JS::CallArgs& args, const js::Wrapper& baseInstance);
|
||||
|
||||
static bool getPrototype(JSContext *cx, JS::HandleObject wrapper,
|
||||
static bool getPrototype(JSContext* cx, JS::HandleObject wrapper,
|
||||
JS::HandleObject target,
|
||||
JS::MutableHandleObject protop);
|
||||
|
||||
virtual void preserveWrapper(JSObject *target) override;
|
||||
virtual void preserveWrapper(JSObject* target) override;
|
||||
|
||||
virtual JSObject* createHolder(JSContext* cx, JSObject* wrapper) override;
|
||||
|
||||
@@ -225,12 +225,12 @@ public:
|
||||
JS::HandleObject holder, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) override;
|
||||
|
||||
bool delete_(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id, JS::ObjectOpResult &result);
|
||||
bool delete_(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, JS::ObjectOpResult& result);
|
||||
|
||||
bool defineProperty(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
bool defineProperty(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined);
|
||||
JS::ObjectOpResult& result, bool* defined);
|
||||
|
||||
virtual bool enumerateNames(JSContext* cx, JS::HandleObject wrapper, unsigned flags,
|
||||
JS::AutoIdVector& props);
|
||||
@@ -322,6 +322,13 @@ public:
|
||||
return static_cast<JSProtoKey>(key);
|
||||
}
|
||||
|
||||
// Operates in the wrapper compartment.
|
||||
static bool getOwnPropertyFromWrapperIfSafe(JSContext* cx,
|
||||
JS::HandleObject wrapper,
|
||||
JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
|
||||
// Like the above, but operates in the target compartment.
|
||||
static bool getOwnPropertyFromTargetIfSafe(JSContext* cx,
|
||||
JS::HandleObject target,
|
||||
JS::HandleObject wrapper,
|
||||
@@ -350,14 +357,14 @@ public:
|
||||
MOZ_CRASH("resolveNativeProperty hook should never be called with HasPrototype = 1");
|
||||
}
|
||||
|
||||
virtual bool resolveOwnProperty(JSContext *cx, const js::Wrapper &jsWrapper, JS::HandleObject wrapper,
|
||||
virtual bool resolveOwnProperty(JSContext* cx, const js::Wrapper& jsWrapper, JS::HandleObject wrapper,
|
||||
JS::HandleObject holder, JS::HandleId id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc) override;
|
||||
|
||||
bool defineProperty(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
bool defineProperty(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
|
||||
JS::Handle<JSPropertyDescriptor> desc,
|
||||
JS::Handle<JSPropertyDescriptor> existingDesc,
|
||||
JS::ObjectOpResult &result, bool *defined)
|
||||
JS::ObjectOpResult& result, bool* defined)
|
||||
{
|
||||
*defined = false;
|
||||
return true;
|
||||
@@ -385,7 +392,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool getPrototype(JSContext *cx, JS::HandleObject wrapper,
|
||||
bool getPrototype(JSContext* cx, JS::HandleObject wrapper,
|
||||
JS::HandleObject target,
|
||||
JS::MutableHandleObject protop)
|
||||
{
|
||||
@@ -434,7 +441,7 @@ class XrayWrapper : public Base {
|
||||
virtual bool ownPropertyKeys(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::AutoIdVector& props) const override;
|
||||
virtual bool delete_(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<jsid> id, JS::ObjectOpResult &result) const override;
|
||||
JS::Handle<jsid> id, JS::ObjectOpResult& result) const override;
|
||||
virtual bool enumerate(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::MutableHandle<JSObject*> objp) const override;
|
||||
virtual bool getPrototype(JSContext* cx, JS::HandleObject wrapper,
|
||||
@@ -442,9 +449,9 @@ class XrayWrapper : public Base {
|
||||
virtual bool setPrototype(JSContext* cx, JS::HandleObject wrapper,
|
||||
JS::HandleObject proto, JS::ObjectOpResult& result) const override;
|
||||
virtual bool setImmutablePrototype(JSContext* cx, JS::HandleObject wrapper,
|
||||
bool *succeeded) const override;
|
||||
virtual bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
bool* succeeded) const override;
|
||||
virtual bool preventExtensions(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::ObjectOpResult& result) const override;
|
||||
virtual bool isExtensible(JSContext* cx, JS::Handle<JSObject*> wrapper, bool* extensible) const override;
|
||||
virtual bool has(JSContext* cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id,
|
||||
bool* bp) const override;
|
||||
@@ -526,7 +533,7 @@ public:
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
|
||||
virtual bool set(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
|
||||
JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver,
|
||||
JS::ObjectOpResult &result) const override;
|
||||
JS::ObjectOpResult& result) const override;
|
||||
|
||||
virtual bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
|
||||
JS::Handle<jsid> id,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
[lock-bad-argument.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
||||
[Test that screen.orientation.lock() throws when the input isn't valid.]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
[lock-basic.html]
|
||||
type: testharness
|
||||
[Test that screen.orientation.unlock() doesn't throw when there is no lock]
|
||||
expected: FAIL
|
||||
|
||||
expected: TIMEOUT
|
||||
[Test that screen.orientation.lock returns a pending promise.]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[Test without 'allow-orientation-lock' sandboxing directive]
|
||||
expected: NOTRUN
|
||||
expected: FAIL
|
||||
|
||||
[Test with 'allow-orientation-lock' sandboxing directive]
|
||||
expected: NOTRUN
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[onchange-event-subframe.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
||||
expected: TIMEOUT
|
||||
[Test subframes receive orientation change events]
|
||||
expected: NOTRUN
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[onchange-event.html]
|
||||
type: testharness
|
||||
expected: ERROR
|
||||
expected: TIMEOUT
|
||||
[Test that orientationchange event is fired when the orientation changes.]
|
||||
expected: NOTRUN
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
[orientation-api.html]
|
||||
type: testharness
|
||||
[Test that the Screen Orientation API is present.]
|
||||
expected: FAIL
|
||||
|
||||
[Test Screen Orientation API property types.]
|
||||
expected: FAIL
|
||||
|
||||
[Test that screen.orientation is an EventTarget.]
|
||||
expected: FAIL
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
[orientation-reading.html]
|
||||
type: testharness
|
||||
[Test screen.orientation properties]
|
||||
expected: FAIL
|
||||
|
||||
[Test screen.orientation default values.]
|
||||
expected: FAIL
|
||||
|
||||
[Test that screen.orientation properties are not writable]
|
||||
expected: FAIL
|
||||
|
||||
[Test that screen.orientation values change if the orientation changes]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
[message-event.html]
|
||||
type: testharness
|
||||
[Properties of the 'message' event]
|
||||
expected: FAIL
|
||||
|
||||
Reference in New Issue
Block a user