summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Nate Moore <natemoo-re@users.noreply.github.com> 2022-01-27 20:36:47 -0600
committerGravatar GitHub <noreply@github.com> 2022-01-27 20:36:47 -0600
commit005751a920c14423648fd45b53cebc94e5108e9f (patch)
tree4e202fee09f2c8dbdfd4d7eceda80bc0bfeb76e3
parent46085e6d8cd0e1a3648411550d5c9174776a44fb (diff)
downloadastro-005751a920c14423648fd45b53cebc94e5108e9f.tar.gz
astro-005751a920c14423648fd45b53cebc94e5108e9f.tar.zst
astro-005751a920c14423648fd45b53cebc94e5108e9f.zip
Add escapeHTML to astro/internal (#2479)
* feat: add escapeHTML to astro/internal * Update packages/astro/src/runtime/server/escape.ts Co-authored-by: Jonathan Neal <jonathantneal@hotmail.com> * Update escape.ts Co-authored-by: Jonathan Neal <jonathantneal@hotmail.com>
-rw-r--r--.changeset/few-papayas-swim.md5
-rw-r--r--packages/astro/src/runtime/server/escape.ts3
-rw-r--r--packages/astro/src/runtime/server/index.ts15
3 files changed, 23 insertions, 0 deletions
diff --git a/.changeset/few-papayas-swim.md b/.changeset/few-papayas-swim.md
new file mode 100644
index 000000000..c8e7dacd0
--- /dev/null
+++ b/.changeset/few-papayas-swim.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Add the `escapeHTML` utility to `astro/internal`
diff --git a/packages/astro/src/runtime/server/escape.ts b/packages/astro/src/runtime/server/escape.ts
new file mode 100644
index 000000000..3b07b2290
--- /dev/null
+++ b/packages/astro/src/runtime/server/escape.ts
@@ -0,0 +1,3 @@
+const entities = { '"': 'quot', '&': 'amp', '\'': 'apos', '<': 'lt', '>': 'gt' } as const
+
+export const escapeHTML = (string: any) => string.replace(/["'&<>]/g, (char: keyof typeof entities) => '&' + entities[char] + ';')
diff --git a/packages/astro/src/runtime/server/index.ts b/packages/astro/src/runtime/server/index.ts
index fb8753cd6..9cdad6877 100644
--- a/packages/astro/src/runtime/server/index.ts
+++ b/packages/astro/src/runtime/server/index.ts
@@ -5,6 +5,7 @@ import shorthash from 'shorthash';
import { extractDirectives, generateHydrateScript } from './hydration.js';
import { serializeListValue } from './util.js';
export { createMetadata } from './metadata.js';
+export { escapeHTML } from './escape.js';
export type { Metadata } from './metadata';
const voidElementNames = /^(area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/i;
@@ -308,12 +309,26 @@ export function createAstro(filePathname: string, site: string, projectRootStr:
const toAttributeString = (value: any) => String(value).replace(/&/g, '&#38;').replace(/"/g, '&#34;');
+const STATIC_DIRECTIVES = new Set([
+ 'set:html',
+ 'set:text'
+])
+
// A helper used to turn expressions into attribute key/value
export function addAttribute(value: any, key: string) {
if (value == null || value === false) {
return '';
}
+ // compiler directives cannot be applied dynamically, log a warning and ignore.
+ if (STATIC_DIRECTIVES.has(key)) {
+ // eslint-disable-next-line no-console
+ console.warn(`[astro] The "${key}" directive cannot be applied dynamically at runtime. It will not be rendered as an attribute.
+
+Make sure to use the static attribute syntax (\`${key}={value}\`) instead of the dynamic spread syntax (\`{...{ "${key}": value }}\`).`);
+ return '';
+ }
+
// support "class" from an expression passed into an element (#782)
if (key === 'class:list') {
return ` ${key.slice(0, -5)}="${toAttributeString(serializeListValue(value))}"`;