feat: support external className prop on Author component
Also restores beforeOutline passthrough in DocLayout.
This commit is contained in:
+62
-43
@@ -2,22 +2,29 @@ import { useFrontmatter } from "@rspress/core/runtime"
|
|||||||
|
|
||||||
// MD5 — self-contained, works in any JS environment
|
// MD5 — self-contained, works in any JS environment
|
||||||
function md5Hex(message: string): string {
|
function md5Hex(message: string): string {
|
||||||
const S = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
const S = [
|
||||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9,
|
||||||
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21,
|
||||||
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]
|
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21,
|
||||||
|
]
|
||||||
|
|
||||||
const T: number[] = []
|
const T: number[] = []
|
||||||
for (let i = 0; i < 64; i++) {
|
for (let i = 0; i < 64; i++) {
|
||||||
T[i] = (Math.floor(Math.abs(Math.sin(i + 1)) * 0x100000000)) | 0
|
T[i] = Math.floor(Math.abs(Math.sin(i + 1)) * 0x100000000) | 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const bytes: number[] = []
|
const bytes: number[] = []
|
||||||
for (let i = 0; i < message.length; i++) {
|
for (let i = 0; i < message.length; i++) {
|
||||||
const c = message.charCodeAt(i)
|
const c = message.charCodeAt(i)
|
||||||
if (c < 0x80) bytes.push(c)
|
if (c < 0x80) bytes.push(c)
|
||||||
else if (c < 0x800) { bytes.push(0xc0 | (c >> 6)); bytes.push(0x80 | (c & 0x3f)) }
|
else if (c < 0x800) {
|
||||||
else { bytes.push(0xe0 | (c >> 12)); bytes.push(0x80 | ((c >> 6) & 0x3f)); bytes.push(0x80 | (c & 0x3f)) }
|
bytes.push(0xc0 | (c >> 6))
|
||||||
|
bytes.push(0x80 | (c & 0x3f))
|
||||||
|
} else {
|
||||||
|
bytes.push(0xe0 | (c >> 12))
|
||||||
|
bytes.push(0x80 | ((c >> 6) & 0x3f))
|
||||||
|
bytes.push(0x80 | (c & 0x3f))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const bitLen = bytes.length * 8
|
const bitLen = bytes.length * 8
|
||||||
@@ -26,39 +33,64 @@ function md5Hex(message: string): string {
|
|||||||
for (let i = 0; i < 4; i++) bytes.push((bitLen >>> (i * 8)) & 0xff)
|
for (let i = 0; i < 4; i++) bytes.push((bitLen >>> (i * 8)) & 0xff)
|
||||||
for (let i = 0; i < 4; i++) bytes.push(0)
|
for (let i = 0; i < 4; i++) bytes.push(0)
|
||||||
|
|
||||||
let a0 = 0x67452301, b0 = 0xefcdab89, c0 = 0x98badcfe, d0 = 0x10325476
|
let a0 = 0x67452301,
|
||||||
|
b0 = 0xefcdab89,
|
||||||
|
c0 = 0x98badcfe,
|
||||||
|
d0 = 0x10325476
|
||||||
|
|
||||||
for (let offset = 0; offset < bytes.length; offset += 64) {
|
for (let offset = 0; offset < bytes.length; offset += 64) {
|
||||||
const M = new Array(16)
|
const M = new Array(16)
|
||||||
for (let i = 0; i < 16; i++) {
|
for (let i = 0; i < 16; i++) {
|
||||||
M[i] = bytes[offset + i * 4] | (bytes[offset + i * 4 + 1] << 8) |
|
M[i] =
|
||||||
(bytes[offset + i * 4 + 2] << 16) | (bytes[offset + i * 4 + 3] << 24)
|
bytes[offset + i * 4] |
|
||||||
|
(bytes[offset + i * 4 + 1] << 8) |
|
||||||
|
(bytes[offset + i * 4 + 2] << 16) |
|
||||||
|
(bytes[offset + i * 4 + 3] << 24)
|
||||||
}
|
}
|
||||||
|
|
||||||
let A = a0, B = b0, C = c0, D = d0
|
let A = a0,
|
||||||
|
B = b0,
|
||||||
|
C = c0,
|
||||||
|
D = d0
|
||||||
|
|
||||||
for (let i = 0; i < 64; i++) {
|
for (let i = 0; i < 64; i++) {
|
||||||
let F: number, g: number
|
let F: number, g: number
|
||||||
if (i < 16) { F = (B & C) | (~B & D); g = i }
|
if (i < 16) {
|
||||||
else if (i < 32) { F = (D & B) | (~D & C); g = (5 * i + 1) % 16 }
|
F = (B & C) | (~B & D)
|
||||||
else if (i < 48) { F = B ^ C ^ D; g = (3 * i + 5) % 16 }
|
g = i
|
||||||
else { F = C ^ (B | ~D); g = (7 * i) % 16 }
|
} else if (i < 32) {
|
||||||
|
F = (D & B) | (~D & C)
|
||||||
|
g = (5 * i + 1) % 16
|
||||||
|
} else if (i < 48) {
|
||||||
|
F = B ^ C ^ D
|
||||||
|
g = (3 * i + 5) % 16
|
||||||
|
} else {
|
||||||
|
F = C ^ (B | ~D)
|
||||||
|
g = (7 * i) % 16
|
||||||
|
}
|
||||||
|
|
||||||
F = (F + A + T[i] + M[g]) | 0
|
F = (F + A + T[i] + M[g]) | 0
|
||||||
A = D; D = C; C = B
|
A = D
|
||||||
|
D = C
|
||||||
|
C = B
|
||||||
B = (B + ((F << S[i]) | (F >>> (32 - S[i])))) | 0
|
B = (B + ((F << S[i]) | (F >>> (32 - S[i])))) | 0
|
||||||
}
|
}
|
||||||
|
|
||||||
a0 = (a0 + A) | 0; b0 = (b0 + B) | 0
|
a0 = (a0 + A) | 0
|
||||||
c0 = (c0 + C) | 0; d0 = (d0 + D) | 0
|
b0 = (b0 + B) | 0
|
||||||
|
c0 = (c0 + C) | 0
|
||||||
|
d0 = (d0 + D) | 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return [a0, b0, c0, d0].map(x =>
|
return [a0, b0, c0, d0]
|
||||||
((x >>> 0) & 0xff).toString(16).padStart(2, "0") +
|
.map(
|
||||||
((x >>> 8) & 0xff).toString(16).padStart(2, "0") +
|
(x) =>
|
||||||
((x >>> 16) & 0xff).toString(16).padStart(2, "0") +
|
((x >>> 0) & 0xff).toString(16).padStart(2, "0") +
|
||||||
((x >>> 24) & 0xff).toString(16).padStart(2, "0")
|
((x >>> 8) & 0xff).toString(16).padStart(2, "0") +
|
||||||
).join("")
|
((x >>> 16) & 0xff).toString(16).padStart(2, "0") +
|
||||||
|
((x >>> 24) & 0xff).toString(16).padStart(2, "0")
|
||||||
|
)
|
||||||
|
.join("")
|
||||||
}
|
}
|
||||||
|
|
||||||
function gravatarUrl(email: string, size = 80): string {
|
function gravatarUrl(email: string, size = 80): string {
|
||||||
@@ -72,35 +104,22 @@ interface AuthorInfo {
|
|||||||
email?: string
|
email?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Author() {
|
export function Author({ className }: { className?: string }) {
|
||||||
const { frontmatter } = useFrontmatter()
|
const { frontmatter } = useFrontmatter()
|
||||||
const author = frontmatter?.author as AuthorInfo | undefined
|
const author = frontmatter?.author as AuthorInfo | undefined
|
||||||
if (!author?.name?.trim()) return null
|
if (!author?.name?.trim()) return null
|
||||||
|
|
||||||
const src = author.email?.trim()
|
const src = author.email?.trim() ? gravatarUrl(author.email) : null
|
||||||
? gravatarUrl(author.email)
|
|
||||||
: null
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
href={author.email?.trim() ? `mailto:${author.email}` : undefined}
|
href={author.email?.trim() ? `mailto:${author.email}` : undefined}
|
||||||
className="author-capsule flex items-center gap-2 my-6 p-1 rounded-full
|
className={`flex items-center gap-2 my-6 p-1 rounded-full
|
||||||
border border-(--rp-c-divider) bg-(--rp-c-bg-soft)
|
border border-(--rp-c-divider) bg-(--rp-c-bg-soft)
|
||||||
no-underline transition-colors hover:bg-(--rp-c-bg-mute)
|
no-underline transition-colors hover:bg-(--rp-c-bg-mute)
|
||||||
cursor-pointer select-none w-fit"
|
cursor-pointer select-none w-fit${className ? ` ${className}` : ""}`}>
|
||||||
>
|
{src && <img src={src} alt={author.name} width={32} height={32} className="rounded-full" />}
|
||||||
{src && (
|
<span className="text-sm text-(--rp-c-text-2) pr-2">{author.name}</span>
|
||||||
<img
|
|
||||||
src={src}
|
|
||||||
alt={author.name}
|
|
||||||
width={32}
|
|
||||||
height={32}
|
|
||||||
className="rounded-full"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<span className="text-sm text-(--rp-c-text-2) pr-2">
|
|
||||||
{author.name}
|
|
||||||
</span>
|
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -10,7 +10,8 @@ function DocLayout(props: DocLayoutProps) {
|
|||||||
{...props}
|
{...props}
|
||||||
beforeOutline={
|
beforeOutline={
|
||||||
<>
|
<>
|
||||||
<Author />
|
<Author className="ml-4 md:ml-0" />
|
||||||
|
{props.beforeOutline}
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
afterDocContent={
|
afterDocContent={
|
||||||
|
|||||||
Reference in New Issue
Block a user