Files
vue-journal-layer/app/components/Journal/CategoryHeader.vue
Jakub Zych a6ee443885 feat: keep Blog Editor markup in the sanitizer and expand Journal embed placeholders into privacy-enhanced iframes
- 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
2026-10-10 12:19:00 +02:00

23 lines
1.1 KiB
Vue

<script setup lang="ts">
// Heading of a category page: name, description and the category's rich
// content, which goes through the Journal sanitizer before v-html. The page
// payload keeps embed placeholders; expandEmbeds turns them into iframes as
// the last step, after sanitizing, and its output is never sanitized again.
import type { JournalCategory } from '../../utils/types.ts'
import { expandEmbeds } from '../../utils/embeds.ts'
import { sanitizeJournalHtml } from '../../utils/htmlGate.ts'
const props = defineProps<{ category: JournalCategory; page?: number }>()
const content = computed(() => expandEmbeds(sanitizeJournalHtml(props.category.content)))
</script>
<template>
<header class="journal-category-header">
<h1 class="journal-category-header__title">
{{ category.name }}<template v-if="page && page > 1"> · {{ $t('journal.pagination.pageTitle', { page }) }}</template>
</h1>
<p v-if="category.description" class="journal-category-header__description">{{ category.description }}</p>
<div v-if="content" class="journal-category-header__content journal-post-body" v-html="content" />
</header>
</template>