Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions packages/qwik/src/core/tests/render-api.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,43 @@ describe('render api', () => {
'(window.qwikevents||(window.qwikevents=[]))'
);
});
it('should not render inside template', async () => {
const bigText = 'hello world '.repeat(3000); // ~30kB of text
const result = await renderToStringAndSetPlatform(
<div>
<Counter />
<table>
<tbody>
<tr>
<td>
<template>
<div>{bigText}</div>
{bigText}
</template>
</td>
</tr>
<tr>
<td>Before here is safe</td>
</tr>
</tbody>
</table>
</div>,
{
containerTagName: 'div',
qwikLoader: 'inline',
}
);
const document = createDocument({ html: result.html });
expect(document.querySelectorAll('script[id=qwikloader]')).toHaveLength(1);
const notQwikLoaderScriptElement = document.body.firstChild?.lastChild
?.previousSibling as HTMLElement;
expect(notQwikLoaderScriptElement?.id).not.toEqual('qwikloader');
// qwik events should still be the last script of body
const eventsScriptElement = document.body.lastChild as HTMLElement;
expect(eventsScriptElement.textContent).toContain(
'(window.qwikevents||(window.qwikevents=[]))'
);
});
});
it('should support never render', async () => {
const result = await renderToStringAndSetPlatform(<Counter />, {
Expand Down
20 changes: 17 additions & 3 deletions packages/qwik/src/server/ssr-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,16 +380,24 @@ class SSRContainer extends _SharedContainer implements ISSRContainer {
return this.closeElement();
}

private $noScriptHere$ = 0;

/** Renders opening tag for DOM element */
openElement(
elementName: string,
varAttrs: SsrAttrs | null,
constAttrs?: SsrAttrs | null,
currentFile?: string | null
): string | undefined {
if (this.qlInclude === QwikLoaderInclude.Inline && this.size > 30 * 1024) {
// We waited long enough, on slow connections the page is already partially visible
this.emitQwikLoaderInline();
if (this.qlInclude === QwikLoaderInclude.Inline) {
if (this.$noScriptHere$ === 0 && this.size > 30 * 1024) {
// We waited long enough, on slow connections the page is already partially visible
this.emitQwikLoaderInline();
}
// keep track of noscript and template
else if (elementName === 'noscript' || elementName === 'template') {
this.$noScriptHere$++;
}
}

let innerHTML: string | undefined = undefined;
Expand Down Expand Up @@ -482,6 +490,12 @@ class SSRContainer extends _SharedContainer implements ISSRContainer {
this.write('>');
}
this.lastNode = null;
if (this.qlInclude === QwikLoaderInclude.Inline) {
// keep track of noscript and template
if (elementName === 'noscript' || elementName === 'template') {
this.$noScriptHere$--;
}
}
}

/** Writes opening data to vNodeData for fragment boundaries */
Expand Down
12 changes: 11 additions & 1 deletion packages/qwik/src/server/tag-nesting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ function isInTable(text: string): TagNesting {
case 'tbody':
case 'tfoot':
return TagNesting.TABLE_BODY;
case 'script':
return TagNesting.TEXT;
default:
return TagNesting.NOT_ALLOWED;
}
Expand All @@ -232,6 +234,8 @@ function isInTableBody(text: string): TagNesting {
switch (text) {
case 'tr':
return TagNesting.TABLE_ROW;
case 'script':
return TagNesting.TEXT;
default:
return TagNesting.NOT_ALLOWED;
}
Expand All @@ -242,6 +246,8 @@ function isInTableRow(text: string): TagNesting {
case 'td':
case 'th':
return TagNesting.ANYTHING;
case 'script':
return TagNesting.TEXT;
default:
return TagNesting.NOT_ALLOWED;
}
Expand All @@ -251,6 +257,8 @@ function isInTableColGroup(text: string): TagNesting {
switch (text) {
case 'col':
return TagNesting.EMPTY;
case 'script':
return TagNesting.TEXT;
default:
return TagNesting.NOT_ALLOWED;
}
Expand All @@ -262,6 +270,8 @@ function isInPicture(text: string): TagNesting {
return TagNesting.EMPTY;
case 'img':
return TagNesting.EMPTY;
case 'script':
return TagNesting.TEXT;
default:
return TagNesting.NOT_ALLOWED;
}
Expand Down Expand Up @@ -331,7 +341,6 @@ function isInPhrasing(text: string, allowInput: boolean): TagNesting {
case 'ruby':
case 's':
case 'samp':
case 'script':
case 'select':
case 'slot':
case 'small':
Expand All @@ -346,6 +355,7 @@ function isInPhrasing(text: string, allowInput: boolean): TagNesting {
case 'video':
case 'wbr':
return allowInput ? TagNesting.PHRASING_ANY : TagNesting.PHRASING_INSIDE_INPUT;
case 'script':
case 'style':
return TagNesting.TEXT;
case 'picture':
Expand Down