Source code

Revision control

Copy as Markdown

Other Tools

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_TabContext_h
#define mozilla_dom_TabContext_h
#include "nsCOMPtr.h"
#include "mozilla/BasePrincipal.h"
#include "nsPIDOMWindow.h"
#include "nsPIWindowRoot.h"
namespace mozilla::dom {
class IPCTabContext;
/**
* TabContext encapsulates information about an iframe.
*
* BrowserParent and BrowserChild both inherit from TabContext, and you can also
* have standalone TabContext objects.
*
* This class is immutable except by calling one of the protected
* SetTabContext*() methods (and those methods can only be called once). See
* also MutableTabContext.
*/
class TabContext {
public:
TabContext();
/* (The implicit copy-constructor and operator= are fine.) */
/**
* Generates IPCTabContext of type BrowserFrameIPCTabContext from this
* TabContext's information.
*/
IPCTabContext AsIPCTabContext() const;
bool IsJSPlugin() const;
int32_t JSPluginId() const;
uint64_t ChromeOuterWindowID() const;
UIStateChangeType ShowFocusRings() const;
uint32_t MaxTouchPoints() const { return mMaxTouchPoints; }
protected:
friend class MaybeInvalidTabContext;
/**
* These protected mutator methods let you modify a TabContext once. Further
* attempts to modify a given TabContext will fail (the method will return
* false).
*
* These mutators will also fail if the TabContext was created with anything
* other than the no-args constructor.
*/
/**
* Set this TabContext to match the given TabContext.
*/
bool SetTabContext(const TabContext& aContext);
bool SetTabContext(uint64_t aChromeOuterWindowID,
UIStateChangeType aShowFocusRings,
uint32_t aMaxTouchPoints);
/**
* Modify this TabContext to match the given TabContext. This is a special
* case triggered by nsFrameLoader::SwapWithOtherRemoteLoader which may have
* caused the owner content to change.
*
* This special case only allows the field `mChromeOuterWindowID` to be
* changed. If any other fields have changed, the update is ignored and
* returns false.
*/
bool UpdateTabContextAfterSwap(const TabContext& aContext);
/**
* Set this TabContext to be for a JS plugin. aPluginID is the id of the JS
* plugin
* (@see nsFakePlugin::mId).
* As with the other protected mutator methods, this lets you modify a
* TabContext once.
* (@see TabContext::SetTabContext above for more details).
*/
bool SetTabContextForJSPluginFrame(int32_t aJSPluginID);
void SetMaxTouchPoints(uint32_t aMaxTouchPoints) {
mMaxTouchPoints = aMaxTouchPoints;
}
private:
/**
* Has this TabContext been initialized? If so, mutator methods will fail.
*/
bool mInitialized;
/**
* The outerWindowID of the window hosting the remote frameloader.
*/
uint64_t mChromeOuterWindowID;
int32_t mJSPluginID;
/**
* Keyboard indicator state (focus rings).
*/
UIStateChangeType mShowFocusRings;
/**
* Maximum number of touch points.
*/
uint32_t mMaxTouchPoints;
};
/**
* MutableTabContext is the same as MaybeInvalidTabContext, except the mutation
* methods are public instead of protected. You can still only call these
* mutation methods once on a given object.
*/
class MutableTabContext : public TabContext {
public:
bool SetTabContext(const TabContext& aContext) {
return TabContext::SetTabContext(aContext);
}
bool SetTabContext(uint64_t aChromeOuterWindowID,
UIStateChangeType aShowFocusRings,
uint32_t aMaxTouchPoints) {
return TabContext::SetTabContext(aChromeOuterWindowID, aShowFocusRings,
aMaxTouchPoints);
}
bool SetTabContextForJSPluginFrame(uint32_t aJSPluginID) {
return TabContext::SetTabContextForJSPluginFrame(aJSPluginID);
}
};
/**
* MaybeInvalidTabContext is a simple class that lets you transform an
* IPCTabContext into a TabContext.
*
* The issue is that an IPCTabContext is not necessarily valid. So to convert
* an IPCTabContext into a TabContext, you construct a MaybeInvalidTabContext,
* check whether it's valid, and, if so, read out your TabContext.
*
* Example usage:
*
* void UseTabContext(const TabContext& aTabContext);
*
* void CreateTab(const IPCTabContext& aContext) {
* MaybeInvalidTabContext tc(aContext);
* if (!tc.IsValid()) {
* NS_ERROR(nsPrintfCString("Got an invalid IPCTabContext: %s",
* tc.GetInvalidReason()));
* return;
* }
* UseTabContext(tc.GetTabContext());
* }
*/
class MaybeInvalidTabContext {
public:
/**
* This constructor copies the information in aContext and sets IsValid() as
* appropriate.
*/
explicit MaybeInvalidTabContext(const IPCTabContext& aContext);
/**
* Was the IPCTabContext we received in our constructor valid?
*/
bool IsValid();
/**
* If IsValid(), this function returns null. Otherwise, it returns a
* human-readable string indicating why the IPCTabContext passed to our
* constructor was not valid.
*/
const char* GetInvalidReason();
/**
* If IsValid(), this function returns a reference to a TabContext
* corresponding to the IPCTabContext passed to our constructor. If
* !IsValid(), this function crashes.
*/
const TabContext& GetTabContext();
private:
MaybeInvalidTabContext(const MaybeInvalidTabContext&) = delete;
MaybeInvalidTabContext& operator=(const MaybeInvalidTabContext&) = delete;
const char* mInvalidReason;
MutableTabContext mTabContext;
};
} // namespace mozilla::dom
#endif