summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dom/base/nsDOMMutationObserver.h7
-rw-r--r--dom/base/nsGlobalWindow.h6
-rw-r--r--dom/base/nsIGlobalObject.cpp38
-rw-r--r--dom/base/nsIGlobalObject.h11
-rw-r--r--dom/webidl/Function.webidl8
-rw-r--r--dom/webidl/WindowOrWorkerGlobalScope.webidl3
-rw-r--r--xpcom/base/CycleCollectedJSContext.h2
7 files changed, 66 insertions, 9 deletions
diff --git a/dom/base/nsDOMMutationObserver.h b/dom/base/nsDOMMutationObserver.h
index 6e17e4f2cc..1e2225d020 100644
--- a/dom/base/nsDOMMutationObserver.h
+++ b/dom/base/nsDOMMutationObserver.h
@@ -25,6 +25,7 @@
#include "nsIDocument.h"
#include "mozilla/dom/Animation.h"
#include "nsIAnimationObserver.h"
+#include "nsGlobalWindow.h"
class nsDOMMutationObserver;
using mozilla::dom::MutationObservingInfo;
@@ -599,11 +600,7 @@ protected:
bool Suppressed()
{
- if (mOwner) {
- nsCOMPtr<nsIDocument> d = mOwner->GetExtantDoc();
- return d && d->IsInSyncOperation();
- }
- return false;
+ return mOwner && nsGlobalWindow::Cast(mOwner)->IsInSyncOperation();
}
static void HandleMutationsInternal(mozilla::AutoSlowOperation& aAso);
diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h
index 00ac023fce..e42835a0b2 100644
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -1224,6 +1224,12 @@ public:
already_AddRefed<nsWindowRoot> GetWindowRoot(mozilla::ErrorResult& aError);
mozilla::dom::Performance* GetPerformance();
+
+ virtual bool IsInSyncOperation() override
+ {
+ return GetExtantDoc() && GetExtantDoc()->IsInSyncOperation();
+ }
+
protected:
// Web IDL helpers
diff --git a/dom/base/nsIGlobalObject.cpp b/dom/base/nsIGlobalObject.cpp
index 8923865082..7a6bab8b4b 100644
--- a/dom/base/nsIGlobalObject.cpp
+++ b/dom/base/nsIGlobalObject.cpp
@@ -4,10 +4,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIGlobalObject.h"
+
+#include "mozilla/CycleCollectedJSContext.h"
+#include "mozilla/dom/FunctionBinding.h"
#include "nsContentUtils.h"
#include "nsThreadUtils.h"
#include "nsHostObjectProtocolHandler.h"
+using mozilla::AutoSlowOperation;
+using mozilla::CycleCollectedJSContext;
+using mozilla::ErrorResult;
+using mozilla::IgnoredErrorResult;
+using mozilla::MicroTaskRunnable;
+using mozilla::dom::VoidFunction;
+
nsIGlobalObject::~nsIGlobalObject()
{
UnlinkHostObjectURIs();
@@ -110,3 +120,31 @@ nsIGlobalObject::TraverseHostObjectURIs(nsCycleCollectionTraversalCallback &aCb)
nsHostObjectProtocolHandler::Traverse(mHostObjectURIs[index], aCb);
}
}
+
+class QueuedMicrotask : public MicroTaskRunnable {
+ public:
+ QueuedMicrotask(nsIGlobalObject* aGlobal, VoidFunction& aCallback)
+ : mGlobal(aGlobal)
+ , mCallback(&aCallback)
+ {}
+
+ /* unsafe */
+ void Run(AutoSlowOperation& aAso) final {
+ IgnoredErrorResult rv;
+ mCallback->Call(static_cast<ErrorResult&>(rv));
+ }
+
+ bool Suppressed() final { return mGlobal->IsInSyncOperation(); }
+
+ private:
+ nsCOMPtr<nsIGlobalObject> mGlobal;
+ RefPtr<VoidFunction> mCallback;
+};
+
+void nsIGlobalObject::QueueMicrotask(VoidFunction& aCallback) {
+ CycleCollectedJSContext* context = CycleCollectedJSContext::Get();
+ if (context) {
+ RefPtr<MicroTaskRunnable> mt = new QueuedMicrotask(this, aCallback);
+ context->DispatchMicroTaskRunnable(mt.forget());
+ }
+} \ No newline at end of file
diff --git a/dom/base/nsIGlobalObject.h b/dom/base/nsIGlobalObject.h
index 6dfae4fbe4..1438803317 100644
--- a/dom/base/nsIGlobalObject.h
+++ b/dom/base/nsIGlobalObject.h
@@ -19,6 +19,13 @@ class nsCString;
class nsCycleCollectionTraversalCallback;
class nsIPrincipal;
+namespace mozilla{
+namespace dom{
+class VoidFunction;
+}
+}
+
+
class nsIGlobalObject : public nsISupports
{
nsTArray<nsCString> mHostObjectURIs;
@@ -72,6 +79,10 @@ public:
void UnlinkHostObjectURIs();
void TraverseHostObjectURIs(nsCycleCollectionTraversalCallback &aCb);
+ virtual bool IsInSyncOperation() { return false; }
+
+ void QueueMicrotask(mozilla::dom::VoidFunction& aCallback);
+
protected:
virtual ~nsIGlobalObject();
diff --git a/dom/webidl/Function.webidl b/dom/webidl/Function.webidl
index 55bec0811c..3b44ee111c 100644
--- a/dom/webidl/Function.webidl
+++ b/dom/webidl/Function.webidl
@@ -6,9 +6,11 @@
* The origin of this IDL file is
* http://www.whatwg.org/specs/web-apps/current-work/#functiocn
*
- * © Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and
- * Opera Software ASA. You are granted a license to use, reproduce
- * and create derivative works of this document.
+ * © Copyright 2004-2022 Apple Computer, Inc., Mozilla Foundation,
+ * Opera Software ASA and Moonchild Productions. You are granted a license to use,
+ * reproduce and create derivative works of this document.
*/
callback Function = any(any... arguments);
+
+callback VoidFunction = void ();
diff --git a/dom/webidl/WindowOrWorkerGlobalScope.webidl b/dom/webidl/WindowOrWorkerGlobalScope.webidl
index dddf2d17c4..652a46ffcb 100644
--- a/dom/webidl/WindowOrWorkerGlobalScope.webidl
+++ b/dom/webidl/WindowOrWorkerGlobalScope.webidl
@@ -36,6 +36,9 @@ interface WindowOrWorkerGlobalScope {
long setInterval(DOMString handler, optional long timeout, any... unused);
void clearInterval(optional long handle = 0);
+ // microtask queuing
+ void queueMicrotask(VoidFunction callback);
+
// ImageBitmap
[Throws]
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource aImage);
diff --git a/xpcom/base/CycleCollectedJSContext.h b/xpcom/base/CycleCollectedJSContext.h
index c39ce62f37..914bb95d30 100644
--- a/xpcom/base/CycleCollectedJSContext.h
+++ b/xpcom/base/CycleCollectedJSContext.h
@@ -137,7 +137,7 @@ struct CycleCollectorResults
class MicroTaskRunnable
{
public:
- MicroTaskRunnable() {}
+ MicroTaskRunnable() = default;
NS_INLINE_DECL_REFCOUNTING(MicroTaskRunnable)
virtual void Run(AutoSlowOperation& aAso) = 0;
virtual bool Suppressed() { return false; }