mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-06 15:58:39 +09:00
Bug 1406922 - Make CycleCollectedJSContext to handle microtasks and make MutationObserver to use them
Tag UXP Issue #1344
This commit is contained in:
parent
fb6f6ec903
commit
249667092c
5 changed files with 164 additions and 48 deletions
|
|
@ -32,8 +32,6 @@ using mozilla::dom::Element;
|
|||
AutoTArray<RefPtr<nsDOMMutationObserver>, 4>*
|
||||
nsDOMMutationObserver::sScheduledMutationObservers = nullptr;
|
||||
|
||||
nsDOMMutationObserver* nsDOMMutationObserver::sCurrentObserver = nullptr;
|
||||
|
||||
uint32_t nsDOMMutationObserver::sMutationLevel = 0;
|
||||
uint64_t nsDOMMutationObserver::sCount = 0;
|
||||
|
||||
|
|
@ -597,10 +595,32 @@ nsDOMMutationObserver::ScheduleForRun()
|
|||
RescheduleForRun();
|
||||
}
|
||||
|
||||
class MutationObserverMicroTask final : public MicroTaskRunnable
|
||||
{
|
||||
public:
|
||||
virtual void Run(AutoSlowOperation& aAso) override
|
||||
{
|
||||
nsDOMMutationObserver::HandleMutations(aAso);
|
||||
}
|
||||
|
||||
virtual bool Suppressed() override
|
||||
{
|
||||
return nsDOMMutationObserver::AllScheduledMutationObserversAreSuppressed();
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
nsDOMMutationObserver::RescheduleForRun()
|
||||
{
|
||||
if (!sScheduledMutationObservers) {
|
||||
CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
|
||||
if (!ccjs) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<MutationObserverMicroTask> momt =
|
||||
new MutationObserverMicroTask();
|
||||
ccjs->DispatchMicroTaskRunnable(momt.forget());
|
||||
sScheduledMutationObservers = new AutoTArray<RefPtr<nsDOMMutationObserver>, 4>;
|
||||
}
|
||||
|
||||
|
|
@ -862,36 +882,9 @@ nsDOMMutationObserver::HandleMutation()
|
|||
mCallback->Call(this, mutations, *this);
|
||||
}
|
||||
|
||||
class AsyncMutationHandler : public mozilla::Runnable
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
nsDOMMutationObserver::HandleMutations();
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
nsDOMMutationObserver::HandleMutationsInternal()
|
||||
nsDOMMutationObserver::HandleMutationsInternal(AutoSlowOperation& aAso)
|
||||
{
|
||||
if (!nsContentUtils::IsSafeToRunScript()) {
|
||||
nsContentUtils::AddScriptRunner(new AsyncMutationHandler());
|
||||
return;
|
||||
}
|
||||
static RefPtr<nsDOMMutationObserver> sCurrentObserver;
|
||||
if (sCurrentObserver && !sCurrentObserver->Suppressed()) {
|
||||
// In normal cases sScheduledMutationObservers will be handled
|
||||
// after previous mutations are handled. But in case some
|
||||
// callback calls a sync API, which spins the eventloop, we need to still
|
||||
// process other mutations happening during that sync call.
|
||||
// This does *not* catch all cases, but should work for stuff running
|
||||
// in separate tabs.
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::AutoSlowOperation aso;
|
||||
|
||||
nsTArray<RefPtr<nsDOMMutationObserver> >* suppressedObservers = nullptr;
|
||||
|
||||
while (sScheduledMutationObservers) {
|
||||
|
|
@ -899,20 +892,21 @@ nsDOMMutationObserver::HandleMutationsInternal()
|
|||
sScheduledMutationObservers;
|
||||
sScheduledMutationObservers = nullptr;
|
||||
for (uint32_t i = 0; i < observers->Length(); ++i) {
|
||||
sCurrentObserver = static_cast<nsDOMMutationObserver*>((*observers)[i]);
|
||||
if (!sCurrentObserver->Suppressed()) {
|
||||
sCurrentObserver->HandleMutation();
|
||||
RefPtr<nsDOMMutationObserver> currentObserver =
|
||||
static_cast<nsDOMMutationObserver*>((*observers)[i]);
|
||||
if (!currentObserver->Suppressed()) {
|
||||
currentObserver->HandleMutation();
|
||||
} else {
|
||||
if (!suppressedObservers) {
|
||||
suppressedObservers = new nsTArray<RefPtr<nsDOMMutationObserver> >;
|
||||
}
|
||||
if (!suppressedObservers->Contains(sCurrentObserver)) {
|
||||
suppressedObservers->AppendElement(sCurrentObserver);
|
||||
if (!suppressedObservers->Contains(currentObserver)) {
|
||||
suppressedObservers->AppendElement(currentObserver);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete observers;
|
||||
aso.CheckForInterrupt();
|
||||
aAso.CheckForInterrupt();
|
||||
}
|
||||
|
||||
if (suppressedObservers) {
|
||||
|
|
@ -923,7 +917,6 @@ nsDOMMutationObserver::HandleMutationsInternal()
|
|||
delete suppressedObservers;
|
||||
suppressedObservers = nullptr;
|
||||
}
|
||||
sCurrentObserver = nullptr;
|
||||
}
|
||||
|
||||
nsDOMMutationRecord*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue