- htmlGate.ts mirrors the four editor-output rules of the Go policy:
figure data-embed (^youtube$) and data-id (^[A-Za-z0-9_-]{11}$),
img alt with any text, ol start (integer)
- embeds.ts: EMBED_PROVIDERS (youtube on youtube-nocookie.com),
EMBED_PLACEHOLDER and expandEmbeds
- JournalPostBody and JournalCategoryHeader render
expandEmbeds(sanitizeJournalHtml(html)); payload transforms only sanitize
- .journal-embed styles (16 / 9 block, borderless iframe)
- tests: byte copy of the editor corpus, mirror and pipeline cases;
acme hello-acme carries a placeholder and the SSR smoke checks the iframe
- README Embeds section and decision note Policy amendment
19 lines
906 B
Vue
19 lines
906 B
Vue
<script setup lang="ts">
|
|
// The post body. v-html only ever receives HTML that went through the Journal
|
|
// sanitizer, which removes what the policy does not allow and keeps the rest.
|
|
// The page passes an already sanitized body (with any embed placeholder still
|
|
// a placeholder); sanitizing again here guards a caller that does not, and
|
|
// gives the same string on server and client. expandEmbeds runs last: it
|
|
// turns the Blog Editor's embed placeholders into privacy-enhanced iframes,
|
|
// and its output is never sanitized again (the sanitizer would strip them).
|
|
import { expandEmbeds } from '../../utils/embeds.ts'
|
|
import { sanitizeJournalHtml } from '../../utils/htmlGate.ts'
|
|
|
|
const props = defineProps<{ html: string | null | undefined }>()
|
|
const html = computed(() => expandEmbeds(sanitizeJournalHtml(props.html)))
|
|
</script>
|
|
|
|
<template>
|
|
<div class="journal-post-body" v-html="html" />
|
|
</template>
|