|
1 | 1 | import { describe, expect, it } from 'vitest' |
| 2 | +import { parseHtmlForUnheadExtraction } from '../../../src/parser' |
2 | 3 | import { transformHtmlTemplate, transformHtmlTemplateRaw } from '../../../src/server/transformHtmlTemplate' |
3 | 4 | import { createServerHeadWithContext } from '../../util' |
4 | 5 |
|
@@ -194,6 +195,74 @@ document.documentElement.dataset.theme = 'dark' |
194 | 195 | <script src="/b.js"></script></head><body>Content</body></html>`) |
195 | 196 | }) |
196 | 197 |
|
| 198 | + it('ends a script at a closing tag in any letter case or followed by a slash or form feed', async () => { |
| 199 | + const head = createServerHeadWithContext() |
| 200 | + |
| 201 | + const html = `<html><head><script>a</SCRIPT><script>b</script/><script>c</script\f><script><!-- d </ScRiPt><script src="/b.js"></script></head><body>Content</body></html>` |
| 202 | + |
| 203 | + const result = await transformHtmlTemplate(head, html) |
| 204 | + expect(result).toBe(`<html><head><script>a</script> |
| 205 | +<script>b</script> |
| 206 | +<script>c</script> |
| 207 | +<script><!-- d </script> |
| 208 | +<script src="/b.js"></script></head><body>Content</body></html>`) |
| 209 | + }) |
| 210 | + |
| 211 | + it('detects a commented nested script in any letter case or followed by a slash or form feed', async () => { |
| 212 | + const head = createServerHeadWithContext() |
| 213 | + |
| 214 | + const html = `<html><head><script><!-- document.write('<SCRIPT src="/a.js"></script>') --></script><script><!-- document.write('<script/></script>') --></script><script><!-- document.write('<script\f></script>') --></script><script src="/b.js"></script></head><body>Content</body></html>` |
| 215 | + |
| 216 | + const result = await transformHtmlTemplate(head, html) |
| 217 | + expect(result).toBe(`<html><head><script><!-- document.write('<SCRIPT src="/a.js"><\\/script>') --></script> |
| 218 | +<script><!-- document.write('<script/><\\/script>') --></script> |
| 219 | +<script><!-- document.write('<script\f><\\/script>') --></script> |
| 220 | +<script src="/b.js"></script></head><body>Content</body></html>`) |
| 221 | + }) |
| 222 | + |
| 223 | + it('leaves a commented nested script at a closing tag in any letter case or followed by a slash or form feed', () => { |
| 224 | + const html = `<html><head><script><!-- <script></SCRIPT>a</script><script><!-- <script></script/>b</script><script><!-- <script></script\f>c</script><script src="/b.js"></script></head><body>Content</body></html>` |
| 225 | + |
| 226 | + expect(parseHtmlForUnheadExtraction(html).input.script).toEqual([ |
| 227 | + { innerHTML: '<!-- <script></SCRIPT>a' }, |
| 228 | + { innerHTML: '<!-- <script></script/>b' }, |
| 229 | + { innerHTML: '<!-- <script></script\f>c' }, |
| 230 | + { src: '/b.js', innerHTML: '' }, |
| 231 | + ]) |
| 232 | + }) |
| 233 | + |
| 234 | + it('does not treat other tag names after <!-- as a nested script', async () => { |
| 235 | + const head = createServerHeadWithContext() |
| 236 | + |
| 237 | + const html = `<html><head><script><!-- <scripts> </script><script><!-- <SCRIPTS> </script><script src="/b.js"></script></head><body>Content</body></html>` |
| 238 | + |
| 239 | + const result = await transformHtmlTemplate(head, html) |
| 240 | + expect(result).toBe(`<html><head><script><!-- <scripts> </script> |
| 241 | +<script><!-- <SCRIPTS> </script> |
| 242 | +<script src="/b.js"></script></head><body>Content</body></html>`) |
| 243 | + }) |
| 244 | + |
| 245 | + it('ends style content at a closing tag in any letter case or followed by a slash or form feed', async () => { |
| 246 | + const head = createServerHeadWithContext() |
| 247 | + |
| 248 | + const html = `<html><head><style>a{}</STYLE><style>b{}</style/><style>c{}</style\f><style>d{}</style></head><body>Content</body></html>` |
| 249 | + |
| 250 | + const result = await transformHtmlTemplate(head, html) |
| 251 | + expect(result).toBe(`<html><head><style>a{}</style> |
| 252 | +<style>b{}</style> |
| 253 | +<style>c{}</style> |
| 254 | +<style>d{}</style></head><body>Content</body></html>`) |
| 255 | + }) |
| 256 | + |
| 257 | + it('ends title content only at a complete closing tag in any letter case', async () => { |
| 258 | + const head = createServerHeadWithContext() |
| 259 | + |
| 260 | + const html = `<html><head><title>a</titles> b</TITLE></head><body>Content</body></html>` |
| 261 | + |
| 262 | + const result = await transformHtmlTemplate(head, html) |
| 263 | + expect(result).toBe(`<html><head><title>a</titles> b</title></head><body>Content</body></html>`) |
| 264 | + }) |
| 265 | + |
197 | 266 | it('handles style tags with complex CSS', async () => { |
198 | 267 | const head = createServerHeadWithContext() |
199 | 268 | head.push({ title: 'Test Title' }) |
|
0 commit comments