From 129b68b939234bd212b80e8130c21696ec432b5e Mon Sep 17 00:00:00 2001 From: zenn Date: Wed, 1 Jul 2026 17:42:12 +0900 Subject: [PATCH] =?UTF-8?q?=EB=9D=BC=EC=9D=B4=ED=8A=B8=EB=B0=95=EC=8A=A4?= =?UTF-8?q?=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=ED=8C=8C=EC=83=9D=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/ContentMarkdownRenderer.vue | 32 ++++++++++- docs/changelog.md | 4 ++ docs/deploy.md | 6 +-- docs/history.md | 4 ++ docs/map.md | 4 +- docs/spec.md | 3 +- docs/todo.md | 3 -- docs/update.md | 8 +++ lib/post-card-thumbnail-url.js | 11 +++- package-lock.json | 4 +- package.json | 2 +- scripts/backfill-post-body-thumbnails.js | 7 ++- server/utils/post-thumbnail-image.js | 53 ++++++++++++++++++- 13 files changed, 122 insertions(+), 19 deletions(-) diff --git a/components/content/ContentMarkdownRenderer.vue b/components/content/ContentMarkdownRenderer.vue index 9f559bd..a793f9a 100644 --- a/components/content/ContentMarkdownRenderer.vue +++ b/components/content/ContentMarkdownRenderer.vue @@ -5,7 +5,11 @@ import { isImageUrl, parseImageMarkdownLine } from '../../lib/markdown-image.js' -import { getPostBodyPreviewThumbnailUrl, getPostBodyThumbnailUrl } from '../../lib/post-card-thumbnail-url.js' +import { + getPostBodyPreviewThumbnailUrl, + getPostBodyThumbnailUrl, + getPostLightboxThumbnailUrl +} from '../../lib/post-card-thumbnail-url.js' import { readEditableTextFromElement, setEditableCaretOffset } from '../../lib/markdown-inline.js' import { applyLiveSelectionDelete, @@ -1057,6 +1061,13 @@ const contentLightboxImages = computed(() => { */ const getContentDisplayImageUrl = (imageUrl) => getPostBodyThumbnailUrl(imageUrl) || imageUrl || '' +/** + * 게시물 라이트박스용 이미지 URL을 조회한다. + * @param {string|null|undefined} imageUrl - 원본 이미지 URL + * @returns {string} 라이트박스용 이미지 URL + */ +const getContentLightboxImageUrl = (imageUrl) => getPostLightboxThumbnailUrl(imageUrl) || imageUrl || '' + /** * 게시물 본문 이미지의 반응형 srcset을 만든다. * @param {string|null|undefined} imageUrl - 원본 이미지 URL @@ -1149,6 +1160,22 @@ const onGalleryImageError = (event, fallbackUrl) => { image.src = fallbackUrl } +/** + * 라이트박스용 파생 이미지 로드 실패 시 원본 이미지로 되돌린다. + * @param {Event} event - 이미지 로드 이벤트 + * @param {string} fallbackUrl - 원본 이미지 URL + * @returns {void} + */ +const onLightboxImageError = (event, fallbackUrl) => { + const image = event.target + + if (!(image instanceof HTMLImageElement) || !fallbackUrl || image.src.endsWith(fallbackUrl)) { + return + } + + image.src = fallbackUrl +} + /** * 갤러리 이미지 셀의 flex 비율 스타일을 만든다. * @param {Object} block - 갤러리 블록 @@ -3621,8 +3648,9 @@ onBeforeUnmount(() => {