Repository: electron/electron
File: shell/renderer/api/electron_api_context_bridge.cc (C++)

Code before:
      v8::Context::Scope destination_context_scope(destination_context);
      return v8::MaybeLocal<v8::Value>(
          elem.ToV8Value(destination_context->GetIsolate()));
    }

    // Custom logic to "clone" Blob references
    blink::WebBlob blob =
        blink::WebBlob::FromV8Value(destination_context->GetIsolate(), value);
    if (!blob.IsNull()) {
      v8::Context::Scope destination_context_scope(destination_context);
      return v8::MaybeLocal<v8::Value>(
          blob.ToV8Value(destination_context->GetIsolate()));
    }

    // Custom logic to "clone" VideoFrame references
    blink::VideoFrame* video_frame =
        blink::V8VideoFrame::ToWrappable(source_context->GetIsolate(), value);
    if (video_frame != nullptr) {
      blink::ScriptState* script_state = blink::ScriptState::ForCurrentRealm(
          destination_context->GetIsolate());
      return v8::MaybeLocal<v8::Value>(
          blink::ToV8Traits<blink::VideoFrame>::ToV8(script_state,
                                                     video_frame));
    }
  }

  // Proxy all objects
  if (IsPlainObject(value)) {
    auto object_value = value.As<v8::Object>();
    auto passed_value = CreateProxyForAPI(
        object_value, source_context, source_execution_context,
        destination_context, object_cache, support_dynamic_properties,
        recursion_depth + 1, error_target);
    if (passed_value.IsEmpty())
      return {};
    return v8::MaybeLocal<v8::Value>(passed_value.ToLocalChecked());
  }

  // Serializable objects
  blink::CloneableMessage ret;
  {
    v8::Local<v8::Context> error_context =
        error_target == BridgeErrorTarget::kSource ? source_context
                                                   : destination_context;
    v8::Context::Scope error_scope(error_context);
    // V8 serializer will throw an error if required
    if (!gin::ConvertFromV8(error_context->GetIsolate(), value, &ret)) {
      return {};
    }
  }


Review comment (suggestion):
Let's document this as a supported type in the contextBridge table
https://www.electronjs.org/docs/latest/api/context-bridge#parameter--error--return-type-support

Code after:
        destination_context->GetIsolate(), value);
    if (!elem.IsNull()) {
      v8::Context::Scope destination_context_scope(destination_context);
      return v8::MaybeLocal<v8::Value>(
          elem.ToV8Value(destination_context->GetIsolate()));
    }

    // Custom logic to "clone" Blob references
    blink::WebBlob blob =
        blink::WebBlob::FromV8Value(destination_context->GetIsolate(), value);
    if (!blob.IsNull()) {
      v8::Context::Scope destination_context_scope(destination_context);
      return v8::MaybeLocal<v8::Value>(
          blob.ToV8Value(destination_context->GetIsolate()));
    }

    // Custom logic to "clone" VideoFrame references
    blink::VideoFrame* video_frame =
        blink::V8VideoFrame::ToWrappable(source_context->GetIsolate(), value);
    if (video_frame != nullptr) {
      blink::ScriptState* script_state = blink::ScriptState::ForCurrentRealm(
          destination_context->GetIsolate());
      return v8::MaybeLocal<v8::Value>(
          blink::ToV8Traits<blink::VideoFrame>::ToV8(script_state,
                                                     video_frame));
    }
  }

  // Proxy all objects
  if (IsPlainObject(value)) {
    auto object_value = value.As<v8::Object>();
    auto passed_value = CreateProxyForAPI(
        object_value, source_context, source_execution_context,
        destination_context, object_cache, support_dynamic_properties,
        recursion_depth + 1, error_target);
    if (passed_value.IsEmpty())
      return {};
    return v8::MaybeLocal<v8::Value>(passed_value.ToLocalChecked());
  }

  // Serializable objects
  blink::CloneableMessage ret;
  {
    v8::Local<v8::Context> error_context =
        error_target == BridgeErrorTarget::kSource ? source_context
                                                   : destination_context;
    v8::Context::Scope error_scope(error_context);
    // V8 serializer will throw an error if required
    if (!gin::ConvertFromV8(error_context->GetIsolate(), value, &ret)) {
      return {};
    }