Skip to content

Commit

Permalink
Keep track of slot position as well
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewp committed Feb 2, 2023
1 parent c4e6ef1 commit c202b3a
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 9 deletions.
5 changes: 4 additions & 1 deletion packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1449,7 +1449,10 @@ export interface SSRResult {
): AstroGlobal;
resolve: (s: string) => Promise<string>;
response: ResponseInit;
scope: 0 | 1 | 2 | 3;
// Bits 1 = astro, 2 = jsx, 4 = slot
// As rendering occurs these bits are manipulated to determine where content
// is within a slot. This is used for head injection.
scope: number;
_metadata: SSRMetadata;
}

Expand Down
2 changes: 1 addition & 1 deletion packages/astro/src/runtime/server/jsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ Did you forget to import the component or is it possible there is a typo?`);
props[key] = value;
}
}
result.scope |= ScopeFlags.JSX;
result.scope |= ScopeFlags.JSX;
return markHTMLString(await renderToString(result, vnode.type as any, props, slots));
}
case !vnode.type && (vnode.type as any) !== 0:
Expand Down
8 changes: 4 additions & 4 deletions packages/astro/src/runtime/server/render/head.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import type { SSRResult } from '../../../@types/astro';
import { markHTMLString } from '../escape.js';
import { renderElement, ScopeFlags } from './util.js';

const AstroAndJSXScope = ScopeFlags.Astro | ScopeFlags.JSX;

// Filter out duplicate elements in our set
const uniqueElements = (item: any, index: number, all: any[]) => {
const props = JSON.stringify(item.props);
Expand Down Expand Up @@ -56,8 +54,10 @@ export function* maybeRenderHead(result: SSRResult) {

// Don't render the head inside of a JSX component that's inside of an Astro component
// as the Astro component will be the one to render the head.
if(result.scope & AstroAndJSXScope) {
return;
switch(result.scope) {
case ScopeFlags.JSX | ScopeFlags.Slot | ScopeFlags.Astro: {
return;
}
}

// This is an instruction informing the page rendering that head might need rendering.
Expand Down
6 changes: 5 additions & 1 deletion packages/astro/src/runtime/server/render/slot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { RenderInstruction } from './types.js';

import { HTMLString, markHTMLString } from '../escape.js';
import { renderChild } from './any.js';
import { ScopeFlags } from './util.js';

const slotString = Symbol.for('astro:slot-string');

Expand All @@ -20,8 +21,9 @@ export function isSlotString(str: string): str is any {
return !!(str as any)[slotString];
}

export async function renderSlot(_result: any, slotted: string, fallback?: any): Promise<string> {
export async function renderSlot(result: SSRResult, slotted: string, fallback?: any): Promise<string> {
if (slotted) {
result.scope |= ScopeFlags.Slot;
let iterator = renderChild(slotted);
let content = '';
let instructions: null | RenderInstruction[] = null;
Expand All @@ -35,6 +37,8 @@ export async function renderSlot(_result: any, slotted: string, fallback?: any):
content += chunk;
}
}
// Remove the flag since we are now outside of the scope.
result.scope &= ~ScopeFlags.Slot;
return markHTMLString(new SlotString(content, instructions));
}
return fallback;
Expand Down
5 changes: 3 additions & 2 deletions packages/astro/src/runtime/server/render/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ export function renderElement(
}

export const ScopeFlags = {
Astro: 1,
JSX: 2
Astro: 1 << 0,
JSX: 1 << 1,
Slot: 1 << 2
};

0 comments on commit c202b3a

Please sign in to comment.