Issue #1587 - Part 2: Implement controller follow/unfollow

This commit is contained in:
Moonchild 2020-06-10 21:33:28 +00:00 • committed by Roy Tam
commit 7207793622
5 changed files with 202 additions and 8 deletions

View file

@ -12,7 +12,8 @@
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FetchController, mGlobal, mSignal)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FetchController, mGlobal, mSignal,
mFollowingSignal)
NS_IMPL_CYCLE_COLLECTING_ADDREF(FetchController)
NS_IMPL_CYCLE_COLLECTING_RELEASE(FetchController)
@ -97,13 +98,29 @@ FetchController::Abort()
void
FetchController::Follow(FetchSignal& aSignal)
{
// TODO
FetchSignal::Follower::Follow(&aSignal);
}
void
FetchController::Unfollow(FetchSignal& aSignal)
{
// TODO
if (mFollowingSignal != &aSignal) {
return;
}
FetchSignal::Follower::Unfollow();
}
FetchSignal*
FetchController::Following() const
{
return mFollowingSignal;
}
void
FetchController::Aborted()
{
Abort();
}
} // dom namespace

View file

@ -8,6 +8,7 @@
#define mozilla_dom_FetchController_h
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/FetchSignal.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "mozilla/ErrorResult.h"
@ -16,10 +17,9 @@
namespace mozilla {
namespace dom {
class FetchSignal;
class FetchController final : public nsISupports
, public nsWrapperCache
, public FetchSignal::Follower
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@ -51,6 +51,13 @@ public:
void
Unfollow(FetchSignal& aSignal);
FetchSignal*
Following() const;
// FetchSignal::Follower
void Aborted() override;
private:
~FetchController() = default;

View file

@ -16,12 +16,12 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(FetchSignal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(FetchSignal,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mController)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mController)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FetchSignal,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mController)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mController)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FetchSignal)
@ -55,6 +55,11 @@ FetchSignal::Abort()
MOZ_ASSERT(!mAborted);
mAborted = true;
// Let's inform the followers.
for (uint32_t i = 0; i < mFollowers.Length(); ++i) {
mFollowers[i]->Aborted();
}
EventInit init;
init.mBubbles = false;
init.mCancelable = false;
@ -65,7 +70,73 @@ FetchSignal::Abort()
Event::Constructor(this, NS_LITERAL_STRING("abort"), init);
event->SetTrusted(true);
DispatchDOMEvent(nullptr, event, nullptr, nullptr);
bool dummy;
DispatchEvent(event, &dummy);
}
void
FetchSignal::AddFollower(FetchSignal::Follower* aFollower)
{
MOZ_DIAGNOSTIC_ASSERT(aFollower);
if (!mFollowers.Contains(aFollower)) {
mFollowers.AppendElement(aFollower);
}
}
void
FetchSignal::RemoveFollower(FetchSignal::Follower* aFollower)
{
MOZ_DIAGNOSTIC_ASSERT(aFollower);
mFollowers.RemoveElement(aFollower);
}
bool
FetchSignal::CanAcceptFollower(FetchSignal::Follower* aFollower) const
{
MOZ_DIAGNOSTIC_ASSERT(aFollower);
if (aFollower == mController) {
return false;
}
FetchSignal* following = mController->Following();
if (!following) {
return true;
}
return following->CanAcceptFollower(aFollower);
}
// FetchSignal::Follower
// ----------------------------------------------------------------------------
FetchSignal::Follower::~Follower()
{
Unfollow();
}
void
FetchSignal::Follower::Follow(FetchSignal* aSignal)
{
MOZ_DIAGNOSTIC_ASSERT(aSignal);
if (!aSignal->CanAcceptFollower(this)) {
return;
}
Unfollow();
mFollowingSignal = aSignal;
aSignal->AddFollower(this);
}
void
FetchSignal::Follower::Unfollow()
{
if (mFollowingSignal) {
mFollowingSignal->RemoveFollower(this);
mFollowingSignal = nullptr;
}
}
} // dom namespace

View file

@ -13,10 +13,29 @@ namespace mozilla {
namespace dom {
class FetchController;
class FetchSignal;
class FetchSignal final : public DOMEventTargetHelper
{
public:
// This class must be implemented by objects who want to follow a FetchSignal.
class Follower
{
public:
virtual void Aborted() = 0;
protected:
virtual ~Follower();
void
Follow(FetchSignal* aSignal);
void
Unfollow();
RefPtr<FetchSignal> mFollowingSignal;
};
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FetchSignal, DOMEventTargetHelper)
@ -33,11 +52,23 @@ public:
IMPL_EVENT_HANDLER(abort);
void
AddFollower(Follower* aFollower);
void
RemoveFollower(Follower* aFollower);
bool
CanAcceptFollower(Follower* aFollower) const;
private:
~FetchSignal() = default;
RefPtr<FetchController> mController;
// Raw pointers. Follower unregisters itself in the DTOR.
nsTArray<Follower*> mFollowers;
bool mAborted;
};