diff --git a/src/adapter/11/bindings.test.ts b/src/adapter/11/bindings.test.ts new file mode 100644 index 00000000..161de71d --- /dev/null +++ b/src/adapter/11/bindings.test.ts @@ -0,0 +1,24 @@ +import { expect } from "vitest"; +import { + getDisplayName, + getPropsVNodeDisplayName, + TYPE_FUNCTION, +} from "./bindings"; + +describe("Preact 11 bindings", () => { + it("should detect context providers without a private back-reference", () => { + const context: any = Object.assign(() => null, { + displayName: "Foobar", + __: "default value", + }); + context.Provider = context; + + const config = { Fragment: () => null }; + expect( + getPropsVNodeDisplayName({ type: context, props: {} } as any, config), + ).to.equal("Foobar.Provider"); + expect( + getDisplayName({ type: context, flags: TYPE_FUNCTION } as any, config), + ).to.equal("Foobar.Provider"); + }); +}); diff --git a/src/adapter/11/bindings.ts b/src/adapter/11/bindings.ts index 58fdbdca..d6cf7d74 100644 --- a/src/adapter/11/bindings.ts +++ b/src/adapter/11/bindings.ts @@ -94,6 +94,10 @@ export function getSuspenseStateKey(c: Component) { return null; } +function getContextProvider(type: any) { + return type.Provider === type ? type : type._contextRef || type.__; +} + // Mangle accessors // When serializing props we're dealing with vnodes instead of @@ -112,7 +116,7 @@ export function getPropsVNodeDisplayName(vnode: VNode, config: RendererConfig) { } // Provider - const ctx = (type as any)._contextRef || (type as any).__; + const ctx = getContextProvider(type); if (ctx && ctx.displayName) { return `${ctx.displayName}.Provider`; } @@ -148,7 +152,7 @@ export function getDisplayName(internal: Internal, config: RendererConfig) { } // Provider - const ctx = (type as any)._contextRef || (type as any).__; + const ctx = getContextProvider(type); if (ctx && ctx.displayName) { return `${ctx.displayName}.Provider`; }