summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/libdeno/binding.cc19
-rw-r--r--core/libdeno/internal.h2
-rw-r--r--js/globals.ts1
-rw-r--r--js/globals_test.ts26
-rw-r--r--js/lib.deno_runtime.d.ts1
5 files changed, 49 insertions, 0 deletions
diff --git a/core/libdeno/binding.cc b/core/libdeno/binding.cc
index 291e62f01..7827cd522 100644
--- a/core/libdeno/binding.cc
+++ b/core/libdeno/binding.cc
@@ -455,6 +455,16 @@ void EvalContext(const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(output);
}
+void QueueMicrotask(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ v8::Isolate* isolate = args.GetIsolate();
+
+ if (!(args[0]->IsFunction())) {
+ ThrowInvalidArgument(isolate);
+ return;
+ }
+ isolate->EnqueueMicrotask(args[0].As<v8::Function>());
+}
+
void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context) {
v8::HandleScope handle_scope(isolate);
v8::Context::Scope context_scope(context);
@@ -493,6 +503,15 @@ void InitializeContext(v8::Isolate* isolate, v8::Local<v8::Context> context) {
CHECK(core_val->SetAccessor(context, deno::v8_str("shared"), Shared)
.FromJust());
+
+ // Direct bindings on `window`.
+ auto queue_microtask_tmpl =
+ v8::FunctionTemplate::New(isolate, QueueMicrotask);
+ auto queue_microtask_val =
+ queue_microtask_tmpl->GetFunction(context).ToLocalChecked();
+ CHECK(
+ global->Set(context, deno::v8_str("queueMicrotask"), queue_microtask_val)
+ .FromJust());
}
void MessageCallback(v8::Local<v8::Message> message,
diff --git a/core/libdeno/internal.h b/core/libdeno/internal.h
index 50e85017e..f3789fcc3 100644
--- a/core/libdeno/internal.h
+++ b/core/libdeno/internal.h
@@ -156,6 +156,7 @@ void ErrorToJSON(const v8::FunctionCallbackInfo<v8::Value>& args);
void Shared(v8::Local<v8::Name> property,
const v8::PropertyCallbackInfo<v8::Value>& info);
void MessageCallback(v8::Local<v8::Message> message, v8::Local<v8::Value> data);
+void QueueMicrotask(const v8::FunctionCallbackInfo<v8::Value>& args);
static intptr_t external_references[] = {
reinterpret_cast<intptr_t>(Print),
reinterpret_cast<intptr_t>(Recv),
@@ -164,6 +165,7 @@ static intptr_t external_references[] = {
reinterpret_cast<intptr_t>(ErrorToJSON),
reinterpret_cast<intptr_t>(Shared),
reinterpret_cast<intptr_t>(MessageCallback),
+ reinterpret_cast<intptr_t>(QueueMicrotask),
0};
static const deno_buf empty_buf = {nullptr, 0};
diff --git a/js/globals.ts b/js/globals.ts
index b47cd80f3..ed7621165 100644
--- a/js/globals.ts
+++ b/js/globals.ts
@@ -89,6 +89,7 @@ window.onload = undefined as undefined | Function;
// standard https://www.w3.org/TR/WebCryptoAPI/#crypto-interface as it does not
// yet incorporate the SubtleCrypto interface as its "subtle" property.
window.crypto = (csprng as unknown) as Crypto;
+// window.queueMicrotask added by hand to self-maintained lib.deno_runtime.d.ts
// When creating the runtime type library, we use modifications to `window` to
// determine what is in the global namespace. When we put a class in the
diff --git a/js/globals_test.ts b/js/globals_test.ts
index 3085118de..42a055087 100644
--- a/js/globals_test.ts
+++ b/js/globals_test.ts
@@ -77,3 +77,29 @@ test(function DenoNamespaceImmutable(): void {
// @ts-ignore
assert(print === Deno.core.print);
});
+
+test(async function windowQueueMicrotask(): Promise<void> {
+ let resolve1: () => void | undefined;
+ let resolve2: () => void | undefined;
+ let microtaskDone = false;
+ const p1 = new Promise(
+ (res): void => {
+ resolve1 = (): void => {
+ microtaskDone = true;
+ res();
+ };
+ }
+ );
+ const p2 = new Promise(
+ (res): void => {
+ resolve2 = (): void => {
+ assert(microtaskDone);
+ res();
+ };
+ }
+ );
+ window.queueMicrotask(resolve1!);
+ setTimeout(resolve2!, 0);
+ await p1;
+ await p2;
+});
diff --git a/js/lib.deno_runtime.d.ts b/js/lib.deno_runtime.d.ts
index bbdc1fcb9..8ece99581 100644
--- a/js/lib.deno_runtime.d.ts
+++ b/js/lib.deno_runtime.d.ts
@@ -1264,6 +1264,7 @@ declare interface Window {
callback: (event: domTypes.Event) => void | null,
options?: boolean | domTypes.EventListenerOptions | undefined
) => void;
+ queueMicrotask: (task: () => void) => void;
Deno: typeof Deno;
}