Page 1 of 1

Get WebWorker javascript context on creation

PostPosted: Wed Sep 20, 2023 3:52 pm
by turtle1

Is there a way to get the CefV8Context for a JS WebWorker when it's created, for example in RenderProcessHandler OnContextCreated? I would like to modify the context object when it's created, the same way it's possible for other normal JS contexts. I found some old discussions about this and the patch in issue 451, but I believe that was back when webkit was used. I do see some code concerning WebWorker task runners but I don't think that's relevant for this purpose. If this isn't currently possible, what modifications would broadly need to be made to CEF / V8 to allow that?

Thank you for your time

Re: Get WebWorker javascript context on creation

PostPosted: Wed Sep 20, 2023 6:02 pm
by magreenblatt
This is not supported. You can add bindings to the main thread context and trigger them via postMessage() from the WebWorker.

Re: Get WebWorker javascript context on creation

PostPosted: Thu Sep 21, 2023 6:28 pm
by turtle1
Thanks, that won't work for our purposes though, unfortunately.

I was able to find a workaround for anyone wondering.
Since AlloyContentRendererClient inherits from chromium's ContentRendererClient, we can override DidInitializeWorkerContextOnWorkerThread in our content renderer client and receive the newly created worker context that way.
This works for both dedicated and shared workers, but obviously now we're working with v8::Local<v8::Context> instead of CefRefPtr<CefV8Context>

Basically something like this (in alloy_content_renderer_client.h) to create a JS variable "myVar" and set it to 42 in the new worker's context;

Code: Select all
virtual void DidInitializeWorkerContextOnWorkerThread(v8::Local<v8::Context> context) override {
    LOG(INFO) << "DidInitializeWorkerContextOnWorkerThread";

    v8::Isolate* isolate = context->GetIsolate();
    v8::MicrotasksScope microtasks_scope(isolate, v8::MicrotasksScope::kDoNotRunMicrotasks);

    v8::Local<v8::Object> global = context->Global();
    v8::Local<v8::String> key = v8::String::NewFromUtf8Literal(isolate, "myVar");
    v8::Local<v8::Value> value = v8::Integer::New(isolate, 42);
    global->Set(context, key, value);

Without kDoNotRunMicrotasks scope we hit a DCHECK in the call to Set.
Use at your own risk. I just figured this out and haven't tested it extensively, no idea if this is safe.