mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-26 11:44:28 +08:00
feat: make svg in markdown scalable
This commit is contained in:
parent
66b72e5149
commit
ede226f74d
@ -32,8 +32,6 @@ export function renderSvgInShadowHost(svgContent: string, hostElement: HTMLEleme
|
||||
}
|
||||
|
||||
svg {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
@ -30,6 +30,7 @@ import { Pluggable } from 'unified'
|
||||
import CodeBlock from './CodeBlock'
|
||||
import Link from './Link'
|
||||
import rehypeHeadingIds from './plugins/rehypeHeadingIds'
|
||||
import rehypeScalableSvg from './plugins/rehypeScalableSvg'
|
||||
import remarkDisableConstructs from './plugins/remarkDisableConstructs'
|
||||
import Table from './Table'
|
||||
|
||||
@ -113,7 +114,7 @@ const Markdown: FC<Props> = ({ block, postProcess }) => {
|
||||
const rehypePlugins = useMemo(() => {
|
||||
const plugins: Pluggable[] = []
|
||||
if (ALLOWED_ELEMENTS.test(messageContent)) {
|
||||
plugins.push(rehypeRaw)
|
||||
plugins.push(rehypeRaw, rehypeScalableSvg)
|
||||
}
|
||||
plugins.push([rehypeHeadingIds, { prefix: `heading-${block.id}` }])
|
||||
if (mathEngine === 'KaTeX') {
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
import type { Element, Root } from 'hast'
|
||||
import { visit } from 'unist-util-visit'
|
||||
|
||||
/**
|
||||
* A Rehype plugin that makes SVG elements scalable.
|
||||
*
|
||||
* This plugin traverses the HAST (HTML Abstract Syntax Tree) and performs
|
||||
* the following operations on each `<svg>` element:
|
||||
*
|
||||
* 1. Ensures a `viewBox` attribute exists. If it's missing but `width` and
|
||||
* `height` are present, it generates a `viewBox` from them. This is
|
||||
* crucial for making the SVG scalable.
|
||||
*
|
||||
* 2. Removes the `width` and `height` attributes. This allows the SVG's size
|
||||
* to be controlled by CSS (e.g., `max-width: 100%`), making it responsive
|
||||
* and preventing it from overflowing its container.
|
||||
*
|
||||
* @returns A unified transformer function.
|
||||
*/
|
||||
function rehypeScalableSvg() {
|
||||
return (tree: Root) => {
|
||||
visit(tree, 'element', (node: Element) => {
|
||||
if (node.tagName === 'svg') {
|
||||
const properties = node.properties || {}
|
||||
const hasViewBox = 'viewBox' in properties
|
||||
const width = properties.width as string | number | undefined
|
||||
const height = properties.height as string | number | undefined
|
||||
|
||||
if (!hasViewBox && width && height) {
|
||||
const numericWidth = parseFloat(String(width))
|
||||
const numericHeight = parseFloat(String(height))
|
||||
if (!isNaN(numericWidth) && !isNaN(numericHeight)) {
|
||||
properties.viewBox = `0 0 ${numericWidth} ${numericHeight}`
|
||||
}
|
||||
}
|
||||
|
||||
// Remove fixed width and height to allow CSS to control the size
|
||||
delete properties.width
|
||||
delete properties.height
|
||||
|
||||
node.properties = properties
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default rehypeScalableSvg
|
||||
@ -291,6 +291,7 @@ export const makeSvgScalable = (element: Element): Element => {
|
||||
const numericHeight = parseFloat(height)
|
||||
if (!isNaN(numericWidth) && !isNaN(numericHeight)) {
|
||||
element.setAttribute('viewBox', `0 0 ${numericWidth} ${numericHeight}`)
|
||||
element.setAttribute('max-width', `${numericWidth}px`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user