fix: avoid image cls in entry content (#666)
This commit is contained in:
parent
a213da80b5
commit
ccda8875e9
|
|
@ -1,5 +1,6 @@
|
|||
import { createElement, Fragment, memo, useEffect, useMemo, useState } from "react"
|
||||
|
||||
import type { MediaInfo } from "~/lib/parse-html"
|
||||
import { parseHtml } from "~/lib/parse-html"
|
||||
import type { RemarkOptions } from "~/lib/parse-markdown"
|
||||
import { parseMarkdown } from "~/lib/parse-markdown"
|
||||
|
|
@ -42,15 +43,17 @@ const HTMLImpl = <A extends keyof JSX.IntrinsicElements = "div">(
|
|||
|
||||
accessory?: React.ReactNode
|
||||
noMedia?: boolean
|
||||
mediaInfo?: MediaInfo
|
||||
} & JSX.IntrinsicElements[A] &
|
||||
Partial<{
|
||||
renderInlineStyle: boolean
|
||||
}>,
|
||||
) => {
|
||||
const { children, renderInlineStyle, as = "div", accessory, noMedia, ...rest } = props
|
||||
const { children, renderInlineStyle, as = "div", accessory, noMedia, mediaInfo, ...rest } = props
|
||||
const [remarkOptions, setRemarkOptions] = useState({
|
||||
renderInlineStyle,
|
||||
noMedia,
|
||||
mediaInfo,
|
||||
})
|
||||
const [shouldForceReMountKey, setShouldForceReMountKey] = useState(0)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export const MarkdownBlockImage = (
|
|||
)}
|
||||
showFallback
|
||||
popper
|
||||
className="inline-flex justify-center"
|
||||
className="flex justify-center"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,9 +152,11 @@ const MediaImpl: FC<MediaProps> = ({
|
|||
mediaLoadState,
|
||||
popper,
|
||||
previewImageUrl,
|
||||
props,
|
||||
props.height,
|
||||
props.width,
|
||||
rest,
|
||||
src,
|
||||
thumbnail,
|
||||
type,
|
||||
])
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,22 @@ import { BlockError } from "~/components/ui/markdown/renderers/BlockErrorBoundar
|
|||
import { createHeadingRenderer } from "~/components/ui/markdown/renderers/Heading"
|
||||
import { Media } from "~/components/ui/media"
|
||||
|
||||
function markInlineImage(node?: Element) {
|
||||
for (const item of node?.children ?? []) {
|
||||
if (item.type === "element" && item.tagName === "img") {
|
||||
;(item.properties as any).inline = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type MediaInfo = Record<string, { width?: number; height?: number }>
|
||||
|
||||
export const parseHtml = (
|
||||
content: string,
|
||||
options?: Partial<{
|
||||
renderInlineStyle: boolean
|
||||
noMedia?: boolean
|
||||
mediaInfo?: MediaInfo
|
||||
}>,
|
||||
) => {
|
||||
const file = new VFile(content)
|
||||
|
|
@ -84,8 +95,17 @@ export const parseHtml = (
|
|||
jsxs: (type, props, key) => jsxs(type as any, props, key),
|
||||
passNode: true,
|
||||
components: {
|
||||
a: ({ node, ...props }) => createElement(MarkdownLink, { ...props } as any),
|
||||
img: Img,
|
||||
a: ({ node, ...props }) => {
|
||||
markInlineImage(node)
|
||||
return createElement(MarkdownLink, { ...props } as any)
|
||||
},
|
||||
img: ({ ...props }) => {
|
||||
return createElement(Img, {
|
||||
...props,
|
||||
width: props.src ? options?.mediaInfo?.[props.src]?.width : props.width,
|
||||
height: props.src ? options?.mediaInfo?.[props.src]?.height : props.height,
|
||||
})
|
||||
},
|
||||
|
||||
h1: createHeadingRenderer(1),
|
||||
h2: createHeadingRenderer(2),
|
||||
|
|
@ -107,6 +127,10 @@ export const parseHtml = (
|
|||
}
|
||||
return createElement(MarkdownP, props, props.children)
|
||||
},
|
||||
span: ({ node, ...props }) => {
|
||||
markInlineImage(node)
|
||||
return createElement("span", props, props.children)
|
||||
},
|
||||
hr: ({ node, ...props }) =>
|
||||
createElement("hr", {
|
||||
...props,
|
||||
|
|
@ -195,7 +219,7 @@ const Img: Components["img"] = ({ node, ...props }) => {
|
|||
type: "photo",
|
||||
...nextProps,
|
||||
|
||||
mediaContainerClassName: tw`max-w-full inline size-auto`,
|
||||
mediaContainerClassName: tw`max-w-full inline rounded-md`,
|
||||
popper: true,
|
||||
className: tw`inline`,
|
||||
showFallback: true,
|
||||
|
|
|
|||
|
|
@ -148,6 +148,17 @@ export const EntryContentRender: Component<{
|
|||
if (!entry) return null
|
||||
|
||||
const content = entry?.entries.content ?? data?.entries.content
|
||||
const mediaInfo = Object.fromEntries(
|
||||
(entry.entries.media ?? data?.entries.media)
|
||||
?.filter((m) => m.type === "photo")
|
||||
.map((cur) => [
|
||||
cur.url,
|
||||
{
|
||||
width: cur.width,
|
||||
height: cur.height,
|
||||
},
|
||||
]) ?? [],
|
||||
)
|
||||
|
||||
return (
|
||||
<EntryContentProvider
|
||||
|
|
@ -200,6 +211,7 @@ export const EntryContentRender: Component<{
|
|||
{!isInReadabilityMode ? (
|
||||
<ShadowDOM>
|
||||
<HTML
|
||||
mediaInfo={mediaInfo}
|
||||
noMedia={noMedia}
|
||||
accessory={contentAccessories}
|
||||
as="article"
|
||||
|
|
|
|||
Loading…
Reference in New Issue