forked from mxx1111/mdlook
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshare-page.ts
More file actions
137 lines (123 loc) · 3.63 KB
/
Copy pathshare-page.ts
File metadata and controls
137 lines (123 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import { sharePageFaviconLink } from './share-head'
import { sharePageCspMeta } from './share-sanitize'
function escapeHtml(text: string): string {
return text
.replace(/&/g, `&`)
.replace(/</g, `<`)
.replace(/>/g, `>`)
.replace(/"/g, `"`)
}
export const SHARE_VIEW_COUNT_PLACEHOLDER = `{{SHARE_VIEW_COUNT}}`
const SHARE_DOOCS_URL = `https://github.com/doocs/md`
const SHARE_FOOTER_STYLES = `
.share-footer {
margin-top: 56px;
padding: 24px 16px 16px;
border-top: 1px solid #ebebeb;
text-align: center;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
.share-footer-inner {
margin: 0;
display: inline-flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 6px 10px;
max-width: 100%;
font-size: 12px;
line-height: 1.6;
color: #888;
}
.share-footer-copy a {
color: #555;
text-decoration: none;
font-weight: 500;
}
.share-footer-divider {
color: #d4d4d4;
user-select: none;
font-weight: 300;
}
.share-footer-meta {
color: #aaa;
font-size: 11px;
letter-spacing: 0.02em;
}`
function buildShareFooterHtml(viewCount: number | string): string {
const count = typeof viewCount === `string`
? viewCount
: String(Math.max(0, Math.floor(viewCount)))
return `<div class="share-footer">
<p class="share-footer-inner">
<span class="share-footer-copy">Copyright © <a href="${SHARE_DOOCS_URL}" target="_blank" rel="noopener noreferrer">Doocs</a>. All rights reserved.</span>
<span class="share-footer-divider" aria-hidden="true">·</span>
<span class="share-footer-meta">阅读 ${count} 次</span>
</p>
</div>`
}
export function buildSharePageHtml(
title: string,
bodyHtml: string,
stylesHtml: string,
): string {
const safeTitle = escapeHtml(title || `Markdown 分享`)
return `<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="robots" content="noindex, nofollow" />
${sharePageCspMeta()}
${sharePageFaviconLink()}
<title>${safeTitle}</title>
${stylesHtml}
<style>
body {
margin: 0;
background: #f5f5f5;
}
.share-page {
max-width: 750px;
margin: 0 auto;
padding: 20px;
background: #ffffff;
box-sizing: border-box;
min-height: 100vh;
}
.share-content {
background: #ffffff;
}
.share-page .diagram-download-bar {
display: none !important;
}
${SHARE_FOOTER_STYLES}
</style>
</head>
<body>
<div class="share-page">
<div class="share-content">
${bodyHtml}
</div>
${buildShareFooterHtml(SHARE_VIEW_COUNT_PLACEHOLDER)}
</div>
</body>
</html>`
}
const LEGACY_FOOTER_RE = /<div class="share-footer">[\s\S]*?<\/div>/
/** 将快照 HTML 中的阅读数占位符替换为当前值(兼容旧版 footer) */
export function injectShareViewCount(html: string, viewCount: number): string {
const safeCount = Math.max(0, Math.floor(viewCount))
const countText = String(safeCount)
let next = html.includes(SHARE_VIEW_COUNT_PLACEHOLDER)
? html.replaceAll(SHARE_VIEW_COUNT_PLACEHOLDER, countText)
: html
if (next.includes(`share-footer-inner`))
return next
if (!LEGACY_FOOTER_RE.test(next))
return next
next = next.replace(LEGACY_FOOTER_RE, buildShareFooterHtml(safeCount))
if (!next.includes(`.share-footer-inner {`))
next = next.replace(`</style>`, `${SHARE_FOOTER_STYLES}\n </style>`)
return next
}