Make Astro.request available to all astro components (#960)

* Make Astro.request available to all astro components

* Adds a changeset
This commit is contained in:
Matthew Phillips 2021-08-03 08:17:03 -04:00 committed by GitHub
parent c2d8cea41f
commit 0334956030
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 53 additions and 15 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Makes Astro.request available in Astro components

View file

@ -163,6 +163,7 @@ function generateAttributes(attrs: Record<string, string>): string {
result += JSON.stringify(key) + ':' + val + ','; result += JSON.stringify(key) + ':' + val + ',';
} }
} }
result += `[__astroContext]:props[__astroContext]`;
return result + '}'; return result + '}';
} }
@ -648,7 +649,7 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
if (node.type === 'Slot') { if (node.type === 'Slot') {
state.importStatements.add(`import { __astro_slot } from 'astro/dist/internal/__astro_slot.js';`); state.importStatements.add(`import { __astro_slot } from 'astro/dist/internal/__astro_slot.js';`);
buffers[curr] += `h(__astro_slot, ${attributes ? generateAttributes(attributes) : 'null'}, children`; buffers[curr] += `h(__astro_slot, ${generateAttributes(attributes)}, children`;
paren++; paren++;
return; return;
} }
@ -661,11 +662,11 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
buffers[curr] += `h(__astro_slot_content, { name: ${attributes.slot} },`; buffers[curr] += `h(__astro_slot_content, { name: ${attributes.slot} },`;
paren++; paren++;
} }
buffers[curr] += `h("${name}", ${attributes ? generateAttributes(attributes) : 'null'}`; buffers[curr] += `h("${name}", ${generateAttributes(attributes)}`;
paren++; paren++;
return; return;
} }
const [componentName, componentKind] = name.split(':'); const [componentName, _componentKind] = name.split(':');
let componentInfo = components.get(componentName); let componentInfo = components.get(componentName);
if (/\./.test(componentName)) { if (/\./.test(componentName)) {
const [componentNamespace] = componentName.split('.'); const [componentNamespace] = componentName.split('.');
@ -691,7 +692,7 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
buffers[curr] += `h(__astro_slot_content, { name: ${attributes.slot} },`; buffers[curr] += `h(__astro_slot_content, { name: ${attributes.slot} },`;
paren++; paren++;
} }
buffers[curr] += `h(${componentName}, ${attributes ? generateAttributes(attributes) : 'null'}`; buffers[curr] += `h(${componentName}, ${generateAttributes(attributes)}`;
paren++; paren++;
return; return;
} else if (!componentInfo && !isCustomElementTag(componentName)) { } else if (!componentInfo && !isCustomElementTag(componentName)) {
@ -705,7 +706,7 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
if (curr === 'markdown') { if (curr === 'markdown') {
await pushMarkdownToBuffer(); await pushMarkdownToBuffer();
} }
buffers[curr] += `,${componentName}.__render(${attributes ? generateAttributes(attributes) : 'null'}),`; buffers[curr] += `,${componentName}.__render(${generateAttributes(attributes)}),`;
} }
curr = 'markdown'; curr = 'markdown';
return; return;
@ -726,7 +727,7 @@ async function compileHtml(enterNode: TemplateNode, state: CodegenState, compile
paren++; paren++;
} }
paren++; paren++;
buffers[curr] += `h(${wrapper}, ${attributes ? generateAttributes(attributes) : 'null'}`; buffers[curr] += `h(${wrapper}, ${generateAttributes(attributes)}`;
} catch (err) { } catch (err) {
paren--; paren--;
// handle errors in scope with filename // handle errors in scope with filename

View file

@ -139,14 +139,26 @@ ${result.createCollection || ''}
// \`__render()\`: Render the contents of the Astro module. // \`__render()\`: Render the contents of the Astro module.
import { h, Fragment } from 'astro/dist/internal/h.js'; import { h, Fragment } from 'astro/dist/internal/h.js';
const __astroInternal = Symbol('astro.internal'); const __astroInternal = Symbol('astro.internal');
const __astroContext = Symbol.for('astro.context');
async function __render(props, ...children) { async function __render(props, ...children) {
const Astro = { const Astro = Object.create(__TopLevelAstro, {
...__TopLevelAstro, props: {
props, value: props,
css: (props[__astroInternal] && props[__astroInternal].css) || [], enumerable: true
request: (props[__astroInternal] && props[__astroInternal].request) || {}, },
isPage: (props[__astroInternal] && props[__astroInternal].isPage) || false, css: {
}; value: (props[__astroInternal] && props[__astroInternal].css) || [],
enumerable: true
},
isPage: {
value: (props[__astroInternal] && props[__astroInternal].isPage) || false,
enumerable: true
},
request: {
value: (props[__astroContext] && props[__astroContext].request) || {},
enumerable: true
}
});
${result.script} ${result.script}
return h(Fragment, null, ${result.html}); return h(Fragment, null, ${result.html});
@ -163,15 +175,22 @@ export async function __renderPage({request, children, props, css}) {
__render, __render,
}; };
Object.defineProperty(props, __astroContext, {
value: {
request
},
writable: false,
enumerable: false
});
Object.defineProperty(props, __astroInternal, { Object.defineProperty(props, __astroInternal, {
value: { value: {
request,
css, css,
isPage: true isPage: true
}, },
writable: false, writable: false,
enumerable: false enumerable: false
}) });
const childBodyResult = await currentChild.__render(props, children); const childBodyResult = await currentChild.__render(props, children);

View file

@ -13,6 +13,8 @@ Global('Astro.request.url', async (context) => {
const $ = doc(result.contents); const $ = doc(result.contents);
assert.equal($('#pathname').text(), '/'); assert.equal($('#pathname').text(), '/');
assert.equal($('#child-pathname').text(), '/');
assert.equal($('#nested-child-pathname').text(), '/');
}); });
Global('Astro.request.canonicalURL', async (context) => { Global('Astro.request.canonicalURL', async (context) => {

View file

@ -0,0 +1,5 @@
---
import NestedChild from './NestedChild.astro';
---
<div id="child-pathname">{Astro.request.url.pathname}</div>
<NestedChild />

View file

@ -0,0 +1 @@
<div id="nested-child-pathname">{Astro.request.url.pathname}</div>

View file

@ -1,3 +1,6 @@
---
import Child from '../components/Child.astro';
---
<html> <html>
<head> <head>
<title>Test</title> <title>Test</title>
@ -6,5 +9,7 @@
<body> <body>
<div id="pathname">{Astro.request.url.pathname}</div> <div id="pathname">{Astro.request.url.pathname}</div>
<a id="site" href={Astro.site}>Home</a> <a id="site" href={Astro.site}>Home</a>
<Child />
</body> </body>
</html> </html>