multi-publisher 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -22
- package/dist/adapters/csdn.js +24 -8
- package/dist/adapters/interface.d.ts +10 -0
- package/dist/adapters/qq.d.ts +19 -0
- package/dist/adapters/qq.js +185 -0
- package/dist/adapters/registry.js +2 -0
- package/dist/adapters/toutiao.d.ts +4 -0
- package/dist/adapters/toutiao.js +163 -49
- package/dist/adapters/wechat-publisher.d.ts +6 -1
- package/dist/adapters/wechat-publisher.js +58 -17
- package/dist/adapters/weixin.d.ts +5 -0
- package/dist/adapters/weixin.js +41 -5
- package/dist/cli/index.js +1 -0
- package/dist/cli/login.js +3 -0
- package/dist/cli/platforms.js +2 -1
- package/dist/cli/publish-all.js +1 -1
- package/dist/cli/publish.d.ts +1 -0
- package/dist/cli/publish.js +29 -5
- package/dist/config.d.ts +8 -0
- package/dist/config.js +11 -0
- package/dist/core/parser.js +9 -1
- package/dist/core/renderer.d.ts +9 -1
- package/dist/core/renderer.js +86 -11
- package/dist/core/theme.d.ts +1 -1
- package/dist/core/theme.js +91 -336
- package/dist/runtime/browser-runtime.js +31 -2
- package/dist/tools/capture.js +28 -4
- package/dist/tools/cover-fetcher.d.ts +10 -0
- package/dist/tools/cover-fetcher.js +100 -0
- package/dist/tools/imgbb-uploader.d.ts +18 -0
- package/dist/tools/imgbb-uploader.js +89 -0
- package/package.json +1 -1
- package/themes/previews/cyberpunk.png +0 -0
- package/themes/previews/nord.png +0 -0
package/dist/core/theme.js
CHANGED
|
@@ -8,6 +8,8 @@ import { fileURLToPath } from 'node:url';
|
|
|
8
8
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
9
|
const THEMES_DIR = path.resolve(__dirname, '../../themes');
|
|
10
10
|
// 默认微信公众号主题 CSS(导出让 renderer.ts 也能用)
|
|
11
|
+
// 排版规范依据微信公众号编辑器:正文 15px / 行高 1.75、浅灰代码块、
|
|
12
|
+
// 浅色左边框引用、图片圆角居中、表格细边框、微信蓝链接。
|
|
11
13
|
export const DEFAULT_CSS = `
|
|
12
14
|
p {
|
|
13
15
|
color: rgb(51, 51, 51);
|
|
@@ -15,27 +17,30 @@ p {
|
|
|
15
17
|
line-height: 1.75em;
|
|
16
18
|
margin: 0 0 1em 0;
|
|
17
19
|
word-wrap: break-word;
|
|
20
|
+
letter-spacing: 0.5px;
|
|
18
21
|
}
|
|
19
22
|
h1, h2, h3, h4, h5, h6 {
|
|
20
23
|
font-weight: bold;
|
|
21
|
-
|
|
24
|
+
color: #2c3e50;
|
|
25
|
+
margin: 1.2em 0 0.6em 0;
|
|
22
26
|
}
|
|
23
|
-
h1 { font-size: 1.
|
|
24
|
-
h2 { font-size: 1.
|
|
27
|
+
h1 { font-size: 1.4em; line-height: 1.4em; border-bottom: 1px solid #e8e8e8; padding-bottom: 0.3em; }
|
|
28
|
+
h2 { font-size: 1.2em; border-left: 4px solid #07a35a; padding-left: 0.5em; }
|
|
25
29
|
h3 { font-size: 1.05em; }
|
|
26
30
|
h4, h5, h6 { font-size: 1em; }
|
|
31
|
+
ul, ol { margin: 0 0 1em 0; padding-left: 1.8em; }
|
|
32
|
+
li { margin: 0.3em 0; line-height: 1.7em; }
|
|
27
33
|
li p { margin: 0; }
|
|
28
|
-
ul, ol { margin: 0; padding-left: 2em; }
|
|
29
|
-
li { margin: 0; padding: 0; line-height: normal; }
|
|
30
|
-
li + li { margin-top: 0.3em; }
|
|
31
34
|
pre {
|
|
32
35
|
background-color: #f6f8fa;
|
|
36
|
+
border: 1px solid #eaecef;
|
|
33
37
|
border-radius: 6px;
|
|
34
|
-
padding: 16px;
|
|
38
|
+
padding: 14px 16px;
|
|
35
39
|
overflow-x: auto;
|
|
36
|
-
font-size:
|
|
40
|
+
font-size: 13.5px;
|
|
37
41
|
line-height: 1.6;
|
|
38
42
|
margin: 1em 0;
|
|
43
|
+
color: #24292e;
|
|
39
44
|
}
|
|
40
45
|
code {
|
|
41
46
|
background-color: rgba(175, 184, 193, 0.2);
|
|
@@ -44,16 +49,24 @@ code {
|
|
|
44
49
|
font-size: 0.9em;
|
|
45
50
|
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
|
46
51
|
}
|
|
47
|
-
pre code { background: none; padding: 0; font-size:
|
|
48
|
-
blockquote {
|
|
49
|
-
|
|
52
|
+
pre code { background: none; padding: 0; border: none; font-size: 13.5px; }
|
|
53
|
+
blockquote {
|
|
54
|
+
border-left: 4px solid #07a35a;
|
|
55
|
+
background-color: #f6fbf8;
|
|
56
|
+
padding: 0.8em 1em;
|
|
57
|
+
margin: 1em 0;
|
|
58
|
+
color: #555;
|
|
59
|
+
border-radius: 0 4px 4px 0;
|
|
60
|
+
}
|
|
61
|
+
hr { border: none; border-top: 1px solid #e8e8e8; margin: 1.5em 0; }
|
|
50
62
|
i, cite, em, var, address { font-style: italic; }
|
|
51
|
-
b, strong { font-weight:
|
|
52
|
-
img { max-width: 100%; height: auto; display: block; margin: 1em auto; }
|
|
53
|
-
table { border-collapse: collapse; width: 100%; margin: 1em 0; }
|
|
54
|
-
table th, table td { border: 1px solid #
|
|
55
|
-
table th { background-color: #f6f8fa; font-weight: bold; }
|
|
56
|
-
|
|
63
|
+
b, strong { font-weight: bold; color: #1a1a1a; }
|
|
64
|
+
img { max-width: 100%; height: auto; display: block; margin: 1em auto; border-radius: 4px; }
|
|
65
|
+
table { border-collapse: collapse; width: 100%; margin: 1em 0; font-size: 14px; }
|
|
66
|
+
table th, table td { border: 1px solid #e8e8e8; padding: 8px 12px; }
|
|
67
|
+
table th { background-color: #f6f8fa; font-weight: bold; color: #2c3e50; }
|
|
68
|
+
table tr:nth-child(even) { background-color: #fafafa; }
|
|
69
|
+
a { color: #576b95; text-decoration: none; border-bottom: 1px solid rgba(87, 107, 149, 0.3); }
|
|
57
70
|
`;
|
|
58
71
|
// 内置主题
|
|
59
72
|
const BUILTIN_THEMES = {
|
|
@@ -64,35 +77,38 @@ const BUILTIN_THEMES = {
|
|
|
64
77
|
},
|
|
65
78
|
wechat: {
|
|
66
79
|
name: 'Wechat',
|
|
67
|
-
description: '
|
|
80
|
+
description: '微信风格,仿微信官方文章排版(白底、微信蓝链接、浅灰代码块)',
|
|
68
81
|
css: `
|
|
69
82
|
p {
|
|
70
|
-
color: rgb(
|
|
83
|
+
color: rgb(62, 62, 62);
|
|
71
84
|
font-size: 15px;
|
|
72
85
|
line-height: 1.75em;
|
|
73
86
|
margin: 0 0 1em 0;
|
|
74
87
|
word-wrap: break-word;
|
|
88
|
+
letter-spacing: 0.5px;
|
|
75
89
|
}
|
|
76
90
|
h1, h2, h3, h4, h5, h6 {
|
|
77
91
|
font-weight: bold;
|
|
78
|
-
|
|
92
|
+
color: #3f3f3f;
|
|
93
|
+
margin: 1.4em 0 0.6em 0;
|
|
79
94
|
}
|
|
80
|
-
h1 { font-size: 1.
|
|
81
|
-
h2 { font-size: 1.
|
|
95
|
+
h1 { font-size: 1.4em; line-height: 1.4em; border-bottom: 1px solid #e8e8e8; padding-bottom: 0.3em; text-align: center; }
|
|
96
|
+
h2 { font-size: 1.2em; border-left: 4px solid #07a35a; padding-left: 0.5em; }
|
|
82
97
|
h3 { font-size: 1.05em; }
|
|
83
98
|
h4, h5, h6 { font-size: 1em; }
|
|
99
|
+
ul, ol { margin: 0 0 1em 0; padding-left: 1.8em; }
|
|
100
|
+
li { margin: 0.35em 0; line-height: 1.7em; }
|
|
84
101
|
li p { margin: 0; }
|
|
85
|
-
ul, ol { margin: 0; padding-left: 2em; }
|
|
86
|
-
li { margin: 0; padding: 0; line-height: normal; }
|
|
87
|
-
li + li { margin-top: 0.3em; }
|
|
88
102
|
pre {
|
|
89
103
|
background-color: #f6f8fa;
|
|
104
|
+
border: 1px solid #eaecef;
|
|
90
105
|
border-radius: 6px;
|
|
91
|
-
padding: 16px;
|
|
106
|
+
padding: 14px 16px;
|
|
92
107
|
overflow-x: auto;
|
|
93
|
-
font-size:
|
|
108
|
+
font-size: 13.5px;
|
|
94
109
|
line-height: 1.6;
|
|
95
110
|
margin: 1em 0;
|
|
111
|
+
color: #24292e;
|
|
96
112
|
}
|
|
97
113
|
code {
|
|
98
114
|
background-color: rgba(175, 184, 193, 0.2);
|
|
@@ -101,330 +117,69 @@ code {
|
|
|
101
117
|
font-size: 0.9em;
|
|
102
118
|
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
|
|
103
119
|
}
|
|
104
|
-
pre code { background: none; padding: 0; font-size:
|
|
105
|
-
blockquote {
|
|
106
|
-
|
|
120
|
+
pre code { background: none; padding: 0; border: none; font-size: 13.5px; }
|
|
121
|
+
blockquote {
|
|
122
|
+
border-left: 3px solid #c8a96e;
|
|
123
|
+
background-color: #faf9f7;
|
|
124
|
+
padding: 0.8em 1em;
|
|
125
|
+
margin: 1em 0;
|
|
126
|
+
color: #666;
|
|
127
|
+
border-radius: 0 4px 4px 0;
|
|
128
|
+
}
|
|
129
|
+
hr { border: none; border-top: 1px solid #e8e8e8; margin: 1.5em 0; }
|
|
107
130
|
i, cite, em, var, address { font-style: italic; }
|
|
108
|
-
b, strong { font-weight:
|
|
131
|
+
b, strong { font-weight: bold; color: #1a1a1a; }
|
|
109
132
|
img { max-width: 100%; height: auto; display: block; margin: 1em auto; border-radius: 4px; }
|
|
110
|
-
table { border-collapse: collapse; width: 100%; margin: 1em 0; }
|
|
111
|
-
table th, table td { border: 1px solid #
|
|
112
|
-
table th { background-color: #f8f8f8; font-weight: bold; }
|
|
133
|
+
table { border-collapse: collapse; width: 100%; margin: 1em 0; font-size: 14px; }
|
|
134
|
+
table th, table td { border: 1px solid #e8e8e8; padding: 8px 12px; }
|
|
135
|
+
table th { background-color: #f8f8f8; font-weight: bold; color: #3f3f3f; }
|
|
136
|
+
table tr:nth-child(even) { background-color: #fafafa; }
|
|
113
137
|
a { color: #576b95; border-bottom: 1px solid rgba(87, 107, 149, 0.3); text-decoration: none; }
|
|
114
138
|
`,
|
|
115
139
|
},
|
|
116
140
|
modern: {
|
|
117
141
|
name: 'Modern',
|
|
118
|
-
description: '
|
|
142
|
+
description: '现代风格,深色代码块清晰层次,适合技术/编程类(知乎、网页友好)',
|
|
119
143
|
css: `
|
|
120
144
|
p { color: rgb(45, 45, 45); font-size: 15.5px; line-height: 1.85em; margin: 0 0 1.3em 0; }
|
|
121
|
-
h1, h2, h3 { font-weight: 700; line-height: 1.35em; color: #
|
|
122
|
-
h1 { font-size: 1.
|
|
123
|
-
h2 { font-size: 1.2em; }
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
145
|
+
h1, h2, h3, h4 { font-weight: 700; line-height: 1.35em; color: #1a1a1a; }
|
|
146
|
+
h1 { font-size: 1.45em; border-bottom: 2px solid #4a90d9; padding-bottom: 0.25em; }
|
|
147
|
+
h2 { font-size: 1.2em; border-left: 4px solid #4a90d9; padding-left: 0.5em; }
|
|
148
|
+
h3 { font-size: 1.05em; }
|
|
149
|
+
h4 { font-size: 1em; color: #555; }
|
|
150
|
+
ul, ol { margin: 0 0 1.2em 0; padding-left: 1.8em; }
|
|
151
|
+
li { margin: 0.35em 0; line-height: 1.7em; }
|
|
152
|
+
pre { background-color: #1e1e1e; border-radius: 8px; padding: 16px 18px; font-size: 13.5px; line-height: 1.6; margin: 1.3em 0; border: 1px solid #333; color: #d4d4d4; }
|
|
153
|
+
code { background-color: rgba(74, 144, 217, 0.12); border-radius: 4px; padding: 0.15em 0.45em; font-size: 0.88em; color: #2f6fb0; font-family: 'SFMono-Regular', Consolas, Menlo, monospace; }
|
|
154
|
+
pre code { background: none; padding: 0; border: none; color: #d4d4d4; }
|
|
155
|
+
blockquote { border-left: 4px solid #4a90d9; background-color: #f0f7ff; padding: 0.8em 1.2em; margin: 1.2em 0; color: #444; border-radius: 0 6px 6px 0; }
|
|
156
|
+
img { border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,0.1); margin: 1.2em 0; max-width: 100%; }
|
|
157
|
+
table { border-collapse: collapse; width: 100%; margin: 1.2em 0; font-size: 14px; }
|
|
158
|
+
table th, table td { border: 1px solid #e1e4e8; padding: 8px 12px; }
|
|
159
|
+
table th { background-color: #4a90d9; color: #fff; font-weight: 600; }
|
|
160
|
+
table tr:nth-child(even) { background-color: #f6f9fc; }
|
|
161
|
+
a { color: #4a90d9; text-decoration: none; border-bottom: 1px solid rgba(74, 144, 217, 0.3); }
|
|
131
162
|
`,
|
|
132
163
|
},
|
|
133
164
|
minimal: {
|
|
134
165
|
name: 'Minimal',
|
|
135
|
-
description: '
|
|
166
|
+
description: '简约风格,干净留白,适合头条号等轻阅读平台',
|
|
136
167
|
css: `
|
|
137
168
|
p { color: rgb(60, 60, 60); font-size: 16px; line-height: 2em; margin: 0 0 1.5em 0; }
|
|
138
|
-
h1 { font-size: 1.5em; text-align: center; letter-spacing: 0.05em; }
|
|
139
|
-
h2 { font-size: 1.25em; border-bottom: 1px solid #eee; padding-bottom: 0.3em; }
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
h1, h2, h3, h4, h5, h6 { font-weight: bold; margin: 1.2em 0 0.6em 0; line-height: 1.4em; }
|
|
153
|
-
h1 { font-size: 1.6em; color: #00fff5; text-shadow: 0 0 20px #00fff5, 0 0 40px #00fff5; border-bottom: 2px solid #ff00ff; padding-bottom: 0.4em; }
|
|
154
|
-
h2 { font-size: 1.3em; color: #ff00ff; text-shadow: 0 0 10px #ff00ff; }
|
|
155
|
-
h3 { font-size: 1.15em; color: #00fff5; }
|
|
156
|
-
li p { margin: 0; }
|
|
157
|
-
ul, ol { margin: 0.8em 0; padding-left: 1.5em; }
|
|
158
|
-
li { margin-bottom: 0.4em; color: #c8c8ff; }
|
|
159
|
-
pre { background: linear-gradient(135deg, #0d022155, #0a0a1f); border: 1px solid #ff00ff33; border-radius: 8px; padding: 16px; overflow-x: auto; font-size: 13.5px; line-height: 1.7; margin: 1em 0; box-shadow: 0 0 20px #ff00ff22; }
|
|
160
|
-
code { background: linear-gradient(90deg, #ff00ff22, #00fff522); border: 1px solid #ff00ff55; border-radius: 4px; padding: 0.2em 0.5em; color: #00fff5; font-size: 0.9em; font-family: 'SF Mono', Consolas, monospace; }
|
|
161
|
-
pre code { background: none; border: none; padding: 0; color: #00fff5; }
|
|
162
|
-
blockquote { border-left: 3px solid #ff00ff; background: linear-gradient(90deg, #ff00ff11, transparent); padding: 0.8rem 1rem; margin: 1em 0; color: #ff88ff; border-radius: 0 4px 4px 0; }
|
|
163
|
-
hr { border: none; border-top: 1px solid #ff00ff44; margin: 2em 0; }
|
|
164
|
-
i, cite, em, var, address { font-style: italic; color: #ff88ff; }
|
|
165
|
-
b, strong { font-weight: bold; color: #fff; }
|
|
166
|
-
img { max-width: 100%; height: auto; display: block; margin: 1em auto; border-radius: 8px; box-shadow: 0 0 20px #00fff544; }
|
|
167
|
-
table { border-collapse: collapse; width: 100%; margin: 1em 0; }
|
|
168
|
-
table th, table td { border: 1px solid #ff00ff44; padding: 8px 12px; }
|
|
169
|
-
table th { background: linear-gradient(90deg, #ff00ff33, #00fff533); color: #00fff5; font-weight: bold; }
|
|
170
|
-
table tr:nth-child(even) { background-color: #ff00ff11; }
|
|
171
|
-
a { color: #00fff5; text-decoration: none; border-bottom: 1px solid #00fff5; }
|
|
172
|
-
a:hover { text-shadow: 0 0 10px #00fff5; }
|
|
173
|
-
`,
|
|
174
|
-
},
|
|
175
|
-
nord: {
|
|
176
|
-
name: 'Nord',
|
|
177
|
-
description: '北欧冷淡风格,蓝灰色调克制简洁',
|
|
178
|
-
css: `
|
|
179
|
-
p { color: #d8dee9; font-size: 15px; line-height: 1.8em; margin: 0 0 1em 0; }
|
|
180
|
-
h1, h2, h3, h4, h5, h6 { font-weight: 600; margin: 1.2em 0 0.6em 0; line-height: 1.4em; }
|
|
181
|
-
h1 { font-size: 1.6em; color: #88c0d0; border-bottom: 2px solid #4c566a; padding-bottom: 0.4em; }
|
|
182
|
-
h2 { font-size: 1.3em; color: #81a1c1; }
|
|
183
|
-
h3 { font-size: 1.15em; color: #88c0d0; }
|
|
184
|
-
li p { margin: 0; }
|
|
185
|
-
ul, ol { margin: 0.8em 0; padding-left: 1.5em; }
|
|
186
|
-
li { margin-bottom: 0.4em; color: #d8dee9; }
|
|
187
|
-
pre { background: #3b4252; border-radius: 8px; padding: 16px; overflow-x: auto; font-size: 13.5px; line-height: 1.7; margin: 1em 0; border-left: 3px solid #88c0d0; }
|
|
188
|
-
code { background: #3b4252; border-radius: 4px; padding: 0.2em 0.5em; color: #a3be8c; font-size: 0.9em; font-family: 'SF Mono', Consolas, monospace; }
|
|
189
|
-
pre code { background: none; padding: 0; color: #eceff4; }
|
|
190
|
-
blockquote { border-left: 3px solid #5e81ac; background: #3b425255; padding: 0.8rem 1rem; margin: 1em 0; color: #d8dee9; font-style: italic; border-radius: 0 4px 4px 0; }
|
|
191
|
-
hr { border: none; border-top: 1px solid #4c566a; margin: 2em 0; }
|
|
192
|
-
i, cite, em, var, address { font-style: italic; }
|
|
193
|
-
b, strong { font-weight: bold; color: #eceff4; }
|
|
194
|
-
img { max-width: 100%; height: auto; display: block; margin: 1em auto; border-radius: 8px; }
|
|
195
|
-
table { border-collapse: collapse; width: 100%; margin: 1em 0; }
|
|
196
|
-
table th, table td { border: 1px solid #4c566a; padding: 8px 12px; }
|
|
197
|
-
table th { background: #3b4252; color: #88c0d0; font-weight: bold; }
|
|
198
|
-
table tr:nth-child(even) { background-color: #3b425255; }
|
|
199
|
-
a { color: #88c0d0; text-decoration: none; }
|
|
200
|
-
a:hover { color: #81a1c1; }
|
|
201
|
-
`,
|
|
202
|
-
},
|
|
203
|
-
paper: {
|
|
204
|
-
name: 'Paper',
|
|
205
|
-
description: '笔记本风格,纸张纹理文艺复古',
|
|
206
|
-
css: `
|
|
207
|
-
body { background-image: linear-gradient(transparent 95%, #e8e4dc 95%); background-size: 100% 2em; }
|
|
208
|
-
p { color: #444; font-size: 15px; line-height: 2em; margin: 0 0 1em 0; text-indent: 2em; }
|
|
209
|
-
h1, h2, h3, h4, h5, h6 { font-weight: bold; margin: 1.5em 0 0.6em 0; line-height: 1.4em; color: #1a1a1a; font-family: Georgia, serif; }
|
|
210
|
-
h1 { font-size: 1.8em; text-align: center; letter-spacing: 0.05em; text-indent: 0; }
|
|
211
|
-
h2 { font-size: 1.4em; color: #2d2d2d; border-bottom: 1px solid #ccc; padding-bottom: 0.3em; text-indent: 0; }
|
|
212
|
-
h3 { font-size: 1.1em; color: #3d3d3d; text-indent: 0; }
|
|
213
|
-
li p { margin: 0; }
|
|
214
|
-
ul, ol { margin: 0.8em 0; padding-left: 2em; }
|
|
215
|
-
li { margin-bottom: 0.4em; color: #444; }
|
|
216
|
-
pre { background: #f5f5f5; border: 1px solid #ddd; border-radius: 6px; padding: 16px; overflow-x: auto; font-size: 13.5px; line-height: 1.6; margin: 1em 0; font-family: 'Courier New', monospace; }
|
|
217
|
-
code { background: #f5f5f5; border: 1px solid #ddd; border-radius: 3px; padding: 0.15em 0.4em; color: #c7254e; font-size: 0.9em; font-family: 'Courier New', monospace; }
|
|
218
|
-
pre code { background: none; border: none; padding: 0; color: #333; }
|
|
219
|
-
blockquote { border-left: 3px solid #c8a96e; background: #f9f7f3; padding: 0.8rem 1rem; margin: 1em 0; color: #666; font-style: italic; border-radius: 0 4px 4px 0; }
|
|
220
|
-
hr { border: none; border-top: 1px solid #ccc; margin: 2em 0; }
|
|
221
|
-
i, cite, em, var, address { font-style: italic; }
|
|
222
|
-
b, strong { font-weight: bold; color: #111; }
|
|
223
|
-
img { max-width: 100%; height: auto; display: block; margin: 1em auto; border-radius: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
|
|
224
|
-
table { border-collapse: collapse; width: 100%; margin: 1em 0; }
|
|
225
|
-
table th, table td { border: 1px solid #ddd; padding: 8px 12px; }
|
|
226
|
-
table th { background: #f5f5f5; color: #333; font-weight: bold; }
|
|
227
|
-
a { color: #0969da; text-decoration: none; border-bottom: 1px dashed #0969da; }
|
|
228
|
-
a:hover { border-bottom-style: solid; }
|
|
229
|
-
`,
|
|
230
|
-
},
|
|
231
|
-
darkelite: {
|
|
232
|
-
name: 'Dark Elite',
|
|
233
|
-
description: '深色精英风格,GitHub 式专业硬核',
|
|
234
|
-
css: `
|
|
235
|
-
p { color: #c9d1d9; font-size: 15px; line-height: 1.8em; margin: 0 0 1em 0; }
|
|
236
|
-
h1, h2, h3, h4, h5, h6 { font-weight: bold; margin: 1.2em 0 0.6em 0; line-height: 1.4em; }
|
|
237
|
-
h1 { font-size: 1.6em; color: #fff; border-bottom: 1px solid #30363d; padding-bottom: 0.4em; }
|
|
238
|
-
h2 { font-size: 1.3em; color: #58a6ff; }
|
|
239
|
-
h3 { font-size: 1.15em; color: #8b949e; }
|
|
240
|
-
li p { margin: 0; }
|
|
241
|
-
ul, ol { margin: 0.8em 0; padding-left: 1.5em; }
|
|
242
|
-
li { margin-bottom: 0.4em; color: #c9d1d9; }
|
|
243
|
-
pre { background: #161b22; border: 1px solid #30363d; border-radius: 6px; padding: 16px; overflow-x: auto; font-size: 13.5px; line-height: 1.7; margin: 1em 0; }
|
|
244
|
-
code { background: #21262d; border: 1px solid #30363d; border-radius: 4px; padding: 0.2em 0.5em; color: #f0883e; font-size: 0.9em; font-family: 'SF Mono', Consolas, monospace; }
|
|
245
|
-
pre code { background: none; border: none; padding: 0; color: #c9d1d9; }
|
|
246
|
-
blockquote { border-left: 3px solid #238636; background: #161b22; padding: 0.8rem 1rem; margin: 1em 0; color: #8b949e; border-radius: 0 4px 4px 0; }
|
|
247
|
-
hr { border: none; border-top: 1px solid #30363d; margin: 2em 0; }
|
|
248
|
-
i, cite, em, var, address { font-style: italic; }
|
|
249
|
-
b, strong { font-weight: bold; color: #fff; }
|
|
250
|
-
img { max-width: 100%; height: auto; display: block; margin: 1em auto; border-radius: 6px; }
|
|
251
|
-
table { border-collapse: collapse; width: 100%; margin: 1em 0; border: 1px solid #30363d; }
|
|
252
|
-
table th, table td { border: 1px solid #30363d; padding: 8px 12px; }
|
|
253
|
-
table th { background: #161b22; color: #58a6ff; font-weight: bold; }
|
|
254
|
-
a { color: #58a6ff; text-decoration: none; }
|
|
255
|
-
a:hover { color: #79c0ff; }
|
|
256
|
-
`,
|
|
257
|
-
},
|
|
258
|
-
sunset: {
|
|
259
|
-
name: 'Sunset',
|
|
260
|
-
description: '日落暖调风格,温暖治愈系',
|
|
261
|
-
css: `
|
|
262
|
-
body { background: linear-gradient(180deg, #1a1a2e 0%, #16213e 50%, #1a1a2e 100%); }
|
|
263
|
-
p { color: #ddd; font-size: 15px; line-height: 1.8em; margin: 0 0 1em 0; }
|
|
264
|
-
h1, h2, h3, h4, h5, h6 { font-weight: bold; margin: 1.2em 0 0.6em 0; line-height: 1.4em; color: #f5f5f5; }
|
|
265
|
-
h1 { font-size: 1.6em; color: #ff6b6b; text-shadow: 0 0 30px #ff6b6b55; text-align: center; }
|
|
266
|
-
h2 { font-size: 1.3em; color: #ffa07a; border-bottom: 1px solid #ffa07a44; padding-bottom: 0.3em; }
|
|
267
|
-
h3 { font-size: 1.15em; color: #ffd93d; }
|
|
268
|
-
li p { margin: 0; }
|
|
269
|
-
ul, ol { margin: 0.8em 0; padding-left: 1.5em; }
|
|
270
|
-
li { margin-bottom: 0.4em; color: #ddd; }
|
|
271
|
-
pre { background: #2d2d44; border-radius: 8px; padding: 16px; overflow-x: auto; font-size: 13.5px; line-height: 1.7; margin: 1em 0; border-left: 3px solid #ff6b6b; }
|
|
272
|
-
code { background: #2d2d44; border-radius: 4px; padding: 0.2em 0.5em; color: #ffd93d; font-size: 0.9em; font-family: 'SF Mono', Consolas, monospace; }
|
|
273
|
-
pre code { background: none; padding: 0; color: #ffa07a; }
|
|
274
|
-
blockquote { background: linear-gradient(90deg, #ff6b6b11, transparent); border-left: 3px solid #ff6b6b; padding: 0.8rem 1rem; margin: 1em 0; color: #bbb; border-radius: 0 4px 4px 0; }
|
|
275
|
-
hr { border: none; border-top: 1px solid #444; margin: 2em 0; }
|
|
276
|
-
i, cite, em, var, address { font-style: italic; color: #ffa07a; }
|
|
277
|
-
b, strong { font-weight: bold; color: #fff; }
|
|
278
|
-
img { max-width: 100%; height: auto; display: block; margin: 1em auto; border-radius: 8px; }
|
|
279
|
-
table { border-collapse: collapse; width: 100%; margin: 1em 0; }
|
|
280
|
-
table th, table td { border: 1px solid #444; padding: 8px 12px; }
|
|
281
|
-
table th { background: #2d2d44; color: #ffd93d; font-weight: bold; }
|
|
282
|
-
a { color: #ffa07a; text-decoration: none; }
|
|
283
|
-
a:hover { color: #ff6b6b; }
|
|
284
|
-
`,
|
|
285
|
-
},
|
|
286
|
-
zen: {
|
|
287
|
-
name: 'Zen',
|
|
288
|
-
description: '禅意风格,日式极简留白',
|
|
289
|
-
css: `
|
|
290
|
-
body { background: #f7f5f0; }
|
|
291
|
-
p { color: #4a4a4a; font-size: 15px; line-height: 2em; margin: 0 0 1.5em 0; }
|
|
292
|
-
h1, h2, h3, h4, h5, h6 { font-weight: normal; margin: 2em 0 0.8em 0; line-height: 1.6em; color: #2d2d2d; font-family: 'Noto Serif SC', 'Songti SC', serif; }
|
|
293
|
-
h1 { font-size: 1.8em; text-align: center; letter-spacing: 0.15em; border-bottom: 1px solid #d4d4d4; padding-bottom: 0.5em; }
|
|
294
|
-
h2 { font-size: 1.4em; letter-spacing: 0.1em; border-left: 3px solid #8b7355; padding-left: 0.8em; }
|
|
295
|
-
h3 { font-size: 1.15em; color: #5a5a5a; }
|
|
296
|
-
li p { margin: 0; }
|
|
297
|
-
ul, ol { margin: 1em 0; padding-left: 1.5em; }
|
|
298
|
-
li { margin-bottom: 0.6em; color: #4a4a4a; line-height: 1.9; }
|
|
299
|
-
pre { background: #ebe8e0; border-radius: 4px; padding: 16px; overflow-x: auto; font-size: 13px; line-height: 1.7; margin: 1.5em 0; border-left: 2px solid #8b7355; }
|
|
300
|
-
code { background: #ebe8e0; border-radius: 3px; padding: 0.15em 0.4em; color: #6b5b4f; font-size: 0.9em; font-family: 'SF Mono', monospace; }
|
|
301
|
-
pre code { background: none; padding: 0; color: #4a4a4a; }
|
|
302
|
-
blockquote { border-left: none; border-top: 1px solid #d4d4d4; border-bottom: 1px solid #d4d4d4; background: none; padding: 1em 1.5em; margin: 2em 0; color: #7a7a7a; font-style: normal; text-align: center; }
|
|
303
|
-
hr { border: none; text-align: center; margin: 3em 0; }
|
|
304
|
-
hr::after { content: '· · ·'; color: #8b7355; letter-spacing: 0.5em; font-size: 1.2em; }
|
|
305
|
-
i, cite, em, var, address { font-style: italic; color: #7a7a7a; }
|
|
306
|
-
b, strong { font-weight: normal; color: #3d3d3d; }
|
|
307
|
-
img { max-width: 100%; height: auto; display: block; margin: 2em auto; border-radius: 2px; }
|
|
308
|
-
table { border-collapse: collapse; width: 100%; margin: 1.5em 0; }
|
|
309
|
-
table th, table td { border: none; border-top: 1px solid #d4d4d4; padding: 10px 12px; }
|
|
310
|
-
table th { color: #8b7355; font-weight: normal; text-align: left; }
|
|
311
|
-
a { color: #8b7355; text-decoration: none; border-bottom: 1px solid transparent; }
|
|
312
|
-
a:hover { border-bottom-color: #8b7355; }
|
|
313
|
-
`,
|
|
314
|
-
},
|
|
315
|
-
retro: {
|
|
316
|
-
name: 'Retro Futurism',
|
|
317
|
-
description: '80年代复古未来主义,霓虹几何',
|
|
318
|
-
css: `
|
|
319
|
-
body { background: #0d0d1a; background-image: repeating-linear-gradient(0deg, transparent, transparent 50px, #1a1a2e 50px, #1a1a2e 51px), repeating-linear-gradient(90deg, transparent, transparent 50px, #1a1a2e 50px, #1a1a2e 51px); }
|
|
320
|
-
p { color: #e0e0e0; font-size: 15px; line-height: 1.8em; margin: 0 0 1em 0; }
|
|
321
|
-
h1, h2, h3, h4, h5, h6 { font-weight: bold; margin: 1.5em 0 0.8em 0; line-height: 1.3em; color: #fff; text-transform: uppercase; letter-spacing: 0.1em; }
|
|
322
|
-
h1 { font-size: 2em; color: #ff6ec7; text-shadow: 3px 3px 0 #00d4ff, -1px -1px 0 #ffff00; transform: skewX(-5deg); }
|
|
323
|
-
h2 { font-size: 1.4em; color: #00d4ff; border-bottom: 2px solid #ff6ec7; padding-bottom: 0.3em; }
|
|
324
|
-
h3 { font-size: 1.15em; color: #ffff00; }
|
|
325
|
-
li p { margin: 0; }
|
|
326
|
-
ul, ol { margin: 1em 0; padding-left: 1.5em; }
|
|
327
|
-
li { margin-bottom: 0.5em; color: #e0e0e0; }
|
|
328
|
-
pre { background: linear-gradient(135deg, #1a1a2e 0%, #0d0d1a 100%); border: 2px solid #ff6ec7; border-radius: 0; padding: 16px; overflow-x: auto; font-size: 13px; line-height: 1.7; margin: 1.5em 0; transform: perspective(500px) rotateX(2deg); box-shadow: 5px 5px 0 #00d4ff; }
|
|
329
|
-
code { background: #ff6ec755; border: 1px solid #ff6ec7; border-radius: 0; padding: 0.2em 0.5em; color: #ff6ec7; font-size: 0.9em; font-family: 'Courier New', monospace; }
|
|
330
|
-
pre code { background: none; border: none; padding: 0; color: #00d4ff; }
|
|
331
|
-
blockquote { border-left: 4px solid #ffff00; background: #1a1a2e; padding: 1rem 1.5rem; margin: 1.5em 0; color: #e0e0e0; transform: skewX(-3deg); }
|
|
332
|
-
hr { border: none; border-top: 2px dashed #ff6ec7; margin: 2.5em 0; }
|
|
333
|
-
i, cite, em, var, address { font-style: italic; color: #ff6ec7; }
|
|
334
|
-
b, strong { font-weight: bold; color: #ffff00; }
|
|
335
|
-
img { max-width: 100%; height: auto; display: block; margin: 1.5em auto; border: 3px solid #00d4ff; filter: contrast(1.1) saturate(1.2); }
|
|
336
|
-
table { border-collapse: separate; border-spacing: 2px; width: 100%; margin: 1.5em 0; }
|
|
337
|
-
table th, table td { background: #1a1a2e; padding: 10px 14px; border: 1px solid #ff6ec7; }
|
|
338
|
-
table th { color: #ffff00; text-align: center; }
|
|
339
|
-
a { color: #00d4ff; text-decoration: none; text-transform: uppercase; }
|
|
340
|
-
a:hover { color: #ff6ec7; text-shadow: 0 0 10px #ff6ec7; }
|
|
341
|
-
`,
|
|
342
|
-
},
|
|
343
|
-
midnight: {
|
|
344
|
-
name: 'Midnight Library',
|
|
345
|
-
description: '深夜图书馆,暖黄灯光书香氛围',
|
|
346
|
-
css: `
|
|
347
|
-
body { background: #0f1a14; background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%231a2f23' fill-opacity='0.3'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); }
|
|
348
|
-
p { color: #d4c5a9; font-size: 15.5px; line-height: 1.9em; margin: 0 0 1.2em 0; font-family: 'Lora', 'Noto Serif SC', Georgia, serif; }
|
|
349
|
-
h1, h2, h3, h4, h5, h6 { font-weight: normal; margin: 1.8em 0 0.8em 0; line-height: 1.5em; color: #f5e6c8; font-family: 'Playfair Display', 'Noto Serif SC', serif; }
|
|
350
|
-
h1 { font-size: 1.9em; text-align: center; letter-spacing: 0.08em; text-shadow: 0 0 40px #ffd70044; border-bottom: 1px solid #3d5a45; padding-bottom: 0.5em; }
|
|
351
|
-
h2 { font-size: 1.4em; color: #c9a962; border-left: 3px solid #8b7355; padding-left: 0.8em; }
|
|
352
|
-
h3 { font-size: 1.15em; color: #b8956e; }
|
|
353
|
-
li p { margin: 0; }
|
|
354
|
-
ul, ol { margin: 1em 0; padding-left: 1.5em; }
|
|
355
|
-
li { margin-bottom: 0.5em; color: #d4c5a9; }
|
|
356
|
-
pre { background: #1a2f23; border: 1px solid #3d5a45; border-radius: 4px; padding: 16px; overflow-x: auto; font-size: 13px; line-height: 1.7; margin: 1.5em 0; box-shadow: inset 0 0 20px #0d1a1444; }
|
|
357
|
-
code { background: #2a3f33; border-radius: 3px; padding: 0.15em 0.4em; color: #ffd700; font-size: 0.9em; font-family: 'Courier New', monospace; }
|
|
358
|
-
pre code { background: none; padding: 0; color: #d4c5a9; }
|
|
359
|
-
blockquote { border-left: 3px solid #8b7355; background: linear-gradient(90deg, #1a2f2344, transparent); padding: 1rem 1.5rem; margin: 2em 0; color: #b8956e; font-style: italic; border-radius: 0 4px 4px 0; }
|
|
360
|
-
hr { border: none; border-top: 1px solid #3d5a45; margin: 3em 0; }
|
|
361
|
-
i, cite, em, var, address { font-style: italic; color: #c9a962; }
|
|
362
|
-
b, strong { font-weight: normal; color: #f5e6c8; }
|
|
363
|
-
img { max-width: 100%; height: auto; display: block; margin: 2em auto; border-radius: 2px; box-shadow: 0 4px 20px #00000055; }
|
|
364
|
-
table { border-collapse: collapse; width: 100%; margin: 1.5em 0; }
|
|
365
|
-
table th, table td { border: 1px solid #3d5a45; padding: 10px 14px; }
|
|
366
|
-
table th { background: #1a2f23; color: #c9a962; text-align: left; }
|
|
367
|
-
a { color: #c9a962; text-decoration: none; border-bottom: 1px dotted #8b7355; }
|
|
368
|
-
a:hover { color: #ffd700; border-bottom-color: #ffd700; }
|
|
369
|
-
`,
|
|
370
|
-
},
|
|
371
|
-
brutalism: {
|
|
372
|
-
name: 'Brutalism',
|
|
373
|
-
description: '粗野主义,大字体原始美学',
|
|
374
|
-
css: `
|
|
375
|
-
body { background: #fff; }
|
|
376
|
-
p { color: #000; font-size: 16px; line-height: 1.6em; margin: 0 0 1em 0; font-weight: 500; }
|
|
377
|
-
h1, h2, h3, h4, h5, h6 { font-weight: 900; margin: 1.5em 0 0.5em 0; line-height: 1.1em; color: #000; text-transform: uppercase; }
|
|
378
|
-
h1 { font-size: 3em; border: 4px solid #000; padding: 0.2em 0.4em; transform: rotate(-1deg); display: inline-block; }
|
|
379
|
-
h2 { font-size: 1.8em; border-bottom: 4px solid #000; padding-bottom: 0.2em; }
|
|
380
|
-
h3 { font-size: 1.3em; }
|
|
381
|
-
li p { margin: 0; }
|
|
382
|
-
ul, ol { margin: 1em 0; padding-left: 1.5em; }
|
|
383
|
-
li { margin-bottom: 0.5em; color: #000; font-weight: 600; }
|
|
384
|
-
pre { background: #000; border-radius: 0; padding: 16px; overflow-x: auto; font-size: 13px; line-height: 1.6; margin: 1.5em 0; }
|
|
385
|
-
code { background: #000; border-radius: 0; padding: 0.2em 0.4em; color: #fff; font-size: 1em; font-family: 'SF Mono', monospace; font-weight: bold; }
|
|
386
|
-
pre code { background: none; padding: 0; color: #fff; }
|
|
387
|
-
blockquote { border: 4px solid #000; background: #f0f0f0; padding: 1rem 1.5rem; margin: 2em 0; }
|
|
388
|
-
blockquote p { font-size: 1.2em; font-weight: 900; margin: 0; }
|
|
389
|
-
hr { border: none; border-top: 4px solid #000; margin: 3em 0; }
|
|
390
|
-
i, cite, em, var, address { font-style: normal; text-decoration: underline; text-decoration-thickness: 3px; }
|
|
391
|
-
b, strong { font-weight: 900; }
|
|
392
|
-
img { max-width: 100%; height: auto; display: block; margin: 1.5em 0; border: 4px solid #000; }
|
|
393
|
-
table { border-collapse: collapse; width: 100%; margin: 1.5em 0; border: 4px solid #000; }
|
|
394
|
-
table th, table td { border: 2px solid #000; padding: 10px 14px; }
|
|
395
|
-
table th { background: #000; color: #fff; font-weight: 900; text-transform: uppercase; }
|
|
396
|
-
a { color: #000; text-decoration: none; background: #ffff00; padding: 0 0.2em; }
|
|
397
|
-
a:hover { background: #000; color: #fff; }
|
|
398
|
-
`,
|
|
399
|
-
},
|
|
400
|
-
neumorphism: {
|
|
401
|
-
name: 'Neumorphism',
|
|
402
|
-
description: '新拟态风格,柔和立体软UI',
|
|
403
|
-
css: `
|
|
404
|
-
body { background: #e0e5ec; }
|
|
405
|
-
p { color: #4a5568; font-size: 15px; line-height: 1.8em; margin: 0 0 1em 0; }
|
|
406
|
-
h1, h2, h3, h4, h5, h6 { font-weight: 600; margin: 1.2em 0 0.6em 0; line-height: 1.4em; color: #2d3748; }
|
|
407
|
-
h1 { font-size: 1.7em; text-align: center; text-shadow: 6px 6px 12px #b8bcc2, -6px -6px 12px #ffffff; padding: 0.5em; }
|
|
408
|
-
h2 { font-size: 1.3em; color: #4a5568; border-left: 4px solid #7c3aed; padding-left: 0.6em; }
|
|
409
|
-
h3 { font-size: 1.1em; color: #5a6577; }
|
|
410
|
-
li p { margin: 0; }
|
|
411
|
-
ul, ol { margin: 0.8em 0; padding-left: 1.5em; }
|
|
412
|
-
li { margin-bottom: 0.5em; color: #4a5568; }
|
|
413
|
-
pre { background: #e0e5ec; border-radius: 16px; padding: 16px; overflow-x: auto; font-size: 13px; line-height: 1.7; margin: 1.2em 0; box-shadow: 8px 8px 16px #b8bcc2, -8px -8px 16px #ffffff; }
|
|
414
|
-
code { background: #e0e5ec; border-radius: 8px; padding: 0.2em 0.5em; color: #7c3aed; font-size: 0.9em; font-family: 'SF Mono', monospace; box-shadow: inset 2px 2px 4px #b8bcc2, inset -2px -2px 4px #ffffff; }
|
|
415
|
-
pre code { background: none; padding: 0; color: #4a5568; box-shadow: none; }
|
|
416
|
-
blockquote { background: #e0e5ec; border-radius: 16px; padding: 1rem 1.5rem; margin: 1.2em 0; color: #5a6577; box-shadow: 8px 8px 16px #b8bcc2, -8px -8px 16px #ffffff; border-left: 4px solid #7c3aed; }
|
|
417
|
-
hr { border: none; margin: 2em 0; }
|
|
418
|
-
hr::after { content: '···'; color: #7c3aed; font-size: 1.5em; letter-spacing: 0.5em; }
|
|
419
|
-
i, cite, em, var, address { font-style: italic; color: #7c3aed; }
|
|
420
|
-
b, strong { font-weight: 600; color: #2d3748; }
|
|
421
|
-
img { max-width: 100%; height: auto; display: block; margin: 1.2em auto; border-radius: 16px; box-shadow: 8px 8px 16px #b8bcc2, -8px -8px 16px #ffffff; }
|
|
422
|
-
table { border-collapse: collapse; width: 100%; margin: 1.2em 0; background: #e0e5ec; border-radius: 16px; overflow: hidden; box-shadow: 8px 8px 16px #b8bcc2, -8px -8px 16px #ffffff; }
|
|
423
|
-
table th, table td { padding: 12px 16px; }
|
|
424
|
-
table th { background: linear-gradient(145deg, #e6ebf2, #d1d9e6); color: #7c3aed; font-weight: 600; }
|
|
425
|
-
table tr:nth-child(even) { background: rgba(124, 58, 237, 0.05); }
|
|
426
|
-
a { color: #7c3aed; text-decoration: none; font-weight: 600; }
|
|
427
|
-
a:hover { color: #5b21b6; text-decoration: underline; }
|
|
169
|
+
h1 { font-size: 1.5em; text-align: center; letter-spacing: 0.05em; font-weight: 700; color: #222; }
|
|
170
|
+
h2 { font-size: 1.25em; border-bottom: 1px solid #eee; padding-bottom: 0.3em; color: #333; }
|
|
171
|
+
h3 { font-size: 1.1em; color: #444; }
|
|
172
|
+
ul, ol { margin: 0 0 1.4em 0; padding-left: 1.6em; }
|
|
173
|
+
li { margin: 0.4em 0; line-height: 1.9em; }
|
|
174
|
+
pre { background-color: #fafafa; border-radius: 6px; border: 1px solid #eee; padding: 14px 16px; overflow-x: auto; font-size: 13.5px; line-height: 1.6; margin: 1.2em 0; }
|
|
175
|
+
code { background-color: rgba(0,0,0,0.04); border-radius: 3px; color: #c7254e; padding: 0.15em 0.4em; font-family: 'SFMono-Regular', Consolas, monospace; }
|
|
176
|
+
pre code { background: none; padding: 0; border: none; }
|
|
177
|
+
blockquote { border-left: none; background: #f9f9f9; font-style: italic; padding: 0.8em 1.2em; margin: 1.4em 0; color: #666; border-radius: 4px; }
|
|
178
|
+
img { border-radius: 4px; margin: 1.2em auto; max-width: 100%; display: block; }
|
|
179
|
+
table { border-collapse: collapse; width: 100%; margin: 1.4em 0; font-size: 14px; }
|
|
180
|
+
table th, table td { border: 1px solid #eee; padding: 8px 12px; }
|
|
181
|
+
table th { background-color: #f5f5f5; font-weight: 600; color: #333; }
|
|
182
|
+
a { color: #0969da; text-decoration: none; }
|
|
428
183
|
`,
|
|
429
184
|
},
|
|
430
185
|
};
|
|
@@ -18,9 +18,28 @@ export class BrowserRuntime {
|
|
|
18
18
|
this.browser = await chromium.launch({
|
|
19
19
|
headless: false, // 需要可见浏览器让用户登录
|
|
20
20
|
channel: 'chromium', // 使用用户的默认 Chrome 配置
|
|
21
|
+
args: [
|
|
22
|
+
'--disable-blink-features=AutomationControlled',
|
|
23
|
+
'--disable-devtools-shm-usage',
|
|
24
|
+
'--no-sandbox',
|
|
25
|
+
],
|
|
26
|
+
});
|
|
27
|
+
// 创建新 context,带真实浏览器配置
|
|
28
|
+
const context = await this.browser.newContext({
|
|
29
|
+
viewport: { width: 1280, height: 900 },
|
|
30
|
+
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
31
|
+
});
|
|
32
|
+
this.page = await context.newPage();
|
|
33
|
+
// 使用 CDP 隐藏自动化特征
|
|
34
|
+
const cdp = await this.page.context().newCDPSession(this.page);
|
|
35
|
+
await cdp.send('Page.addScriptToEvaluateOnNewDocument', {
|
|
36
|
+
source: `
|
|
37
|
+
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
|
|
38
|
+
Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5] });
|
|
39
|
+
Object.defineProperty(navigator, 'languages', { get: () => ['zh-CN', 'zh', 'en'] });
|
|
40
|
+
window.chrome = { runtime: {}, loadTimes: () => {}, csi: () => {} };
|
|
41
|
+
`
|
|
21
42
|
});
|
|
22
|
-
// 不创建新context,让Playwright使用默认context,保持已登录状态
|
|
23
|
-
this.page = await this.browser.newPage();
|
|
24
43
|
// 注意:不清理 cookies,使用用户已有的登录状态
|
|
25
44
|
console.log(`打开登录页面: ${loginConfig.loginUrl}`);
|
|
26
45
|
await this.page.goto(loginConfig.loginUrl, { waitUntil: 'domcontentloaded', timeout: 60000 });
|
|
@@ -397,6 +416,16 @@ export const PLATFORM_LOGIN_CONFIGS = {
|
|
|
397
416
|
},
|
|
398
417
|
extraCookieDomains: ['.51cto.com', '.cto51.com'],
|
|
399
418
|
},
|
|
419
|
+
qq: {
|
|
420
|
+
id: 'qq',
|
|
421
|
+
name: '企鹅号',
|
|
422
|
+
loginUrl: 'https://om.qq.com/',
|
|
423
|
+
successCondition: {
|
|
424
|
+
cookieName: 'userid',
|
|
425
|
+
waitMs: 60000,
|
|
426
|
+
},
|
|
427
|
+
extraCookieDomains: ['.qq.com', '.om.qq.com'],
|
|
428
|
+
},
|
|
400
429
|
};
|
|
401
430
|
/**
|
|
402
431
|
* 执行平台登录
|
package/dist/tools/capture.js
CHANGED
|
@@ -39,6 +39,10 @@ const PLATFORM_CONFIGS = {
|
|
|
39
39
|
editorUrl: 'https://weibo.com/compose',
|
|
40
40
|
uploadPatterns: [/upload/i, /file/i, /image/i, /img/i],
|
|
41
41
|
},
|
|
42
|
+
qq: {
|
|
43
|
+
editorUrl: 'https://om.qq.com/main/creation/article',
|
|
44
|
+
uploadPatterns: [/upload/i, /file/i, /image/i, /img/i, /cover/i],
|
|
45
|
+
},
|
|
42
46
|
};
|
|
43
47
|
function isUploadRequest(url, headers, postData) {
|
|
44
48
|
const contentType = headers['content-type'] || '';
|
|
@@ -65,6 +69,7 @@ async function loadCookies(platform) {
|
|
|
65
69
|
case 'toutiao': return await ConfigStore.getToutiaoCookies() || {};
|
|
66
70
|
case 'jianshu': return await ConfigStore.getJianshuCookies() || {};
|
|
67
71
|
case 'weibo': return await ConfigStore.getWeiboCookies() || {};
|
|
72
|
+
case 'qq': return await ConfigStore.getQQCookies() || {};
|
|
68
73
|
default: return {};
|
|
69
74
|
}
|
|
70
75
|
}
|
|
@@ -80,6 +85,7 @@ function getCookieDomains(platform) {
|
|
|
80
85
|
toutiao: ['.toutiao.com'],
|
|
81
86
|
jianshu: ['.jianshu.com'],
|
|
82
87
|
weibo: ['.weibo.com', '.sina.com.cn'],
|
|
88
|
+
qq: ['.qq.com', '.om.qq.com'],
|
|
83
89
|
};
|
|
84
90
|
return domains[platform] || [];
|
|
85
91
|
}
|
|
@@ -112,9 +118,27 @@ export async function capture(platform, timeoutMs = 60000) {
|
|
|
112
118
|
const browser = await chromium.launch({
|
|
113
119
|
headless: false,
|
|
114
120
|
channel: 'chromium',
|
|
121
|
+
args: [
|
|
122
|
+
'--disable-blink-features=AutomationControlled',
|
|
123
|
+
'--disable-devtools-shm-usage',
|
|
124
|
+
'--no-sandbox',
|
|
125
|
+
],
|
|
126
|
+
});
|
|
127
|
+
const context = await browser.newContext({
|
|
128
|
+
viewport: { width: 1280, height: 900 },
|
|
129
|
+
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
115
130
|
});
|
|
116
|
-
const context = await browser.newContext();
|
|
117
131
|
const page = await context.newPage();
|
|
132
|
+
// 使用 CDP 隐藏自动化特征
|
|
133
|
+
const cdp = await page.context().newCDPSession(page);
|
|
134
|
+
await cdp.send('Page.addScriptToEvaluateOnNewDocument', {
|
|
135
|
+
source: `
|
|
136
|
+
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
|
|
137
|
+
Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3, 4, 5] });
|
|
138
|
+
Object.defineProperty(navigator, 'languages', { get: () => ['zh-CN', 'zh', 'en'] });
|
|
139
|
+
window.chrome = { runtime: {}, loadTimes: () => {}, csi: () => {} };
|
|
140
|
+
`
|
|
141
|
+
});
|
|
118
142
|
// 设置 cookies
|
|
119
143
|
const cookieDomains = getCookieDomains(platform);
|
|
120
144
|
for (const [name, value] of Object.entries(cookies)) {
|
|
@@ -142,8 +166,8 @@ export async function capture(platform, timeoutMs = 60000) {
|
|
|
142
166
|
const headers = request.headers();
|
|
143
167
|
const method = request.method();
|
|
144
168
|
const contentType = headers['content-type'] || '';
|
|
145
|
-
// 只记录 API
|
|
146
|
-
if (!url.includes('api') && !url.includes('bizapi')) {
|
|
169
|
+
// 只记录 API 请求(放宽过滤条件以捕获 QQ 的特殊接口)
|
|
170
|
+
if (!url.includes('api') && !url.includes('bizapi') && !url.includes('.om.qq.com') && !url.includes('editorCache')) {
|
|
147
171
|
return;
|
|
148
172
|
}
|
|
149
173
|
const captured = {
|
|
@@ -224,7 +248,7 @@ export async function capture(platform, timeoutMs = 60000) {
|
|
|
224
248
|
});
|
|
225
249
|
// 打开编辑器
|
|
226
250
|
console.log(`\n🌐 打开编辑器: ${config.editorUrl}`);
|
|
227
|
-
await page.goto(config.editorUrl, { waitUntil: '
|
|
251
|
+
await page.goto(config.editorUrl, { waitUntil: 'domcontentloaded', timeout: 60000 });
|
|
228
252
|
console.log('✅ 编辑器已加载');
|
|
229
253
|
console.log('\n📋 操作提示:');
|
|
230
254
|
console.log(' 1. 在编辑器中找到上传图片功能');
|
|
@@ -19,3 +19,13 @@ export declare function fetchCoverByTitle(title: string, options?: {
|
|
|
19
19
|
* 清理临时封面文件
|
|
20
20
|
*/
|
|
21
21
|
export declare function cleanupCoverFile(localPath: string | undefined): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* 下载远程封面图片到本地临时目录
|
|
24
|
+
* @param coverUrl 远程图片 URL
|
|
25
|
+
* @param options 配置选项
|
|
26
|
+
* @returns 本地临时文件路径
|
|
27
|
+
*/
|
|
28
|
+
export declare function downloadCoverUrl(coverUrl: string, options?: {
|
|
29
|
+
timeout?: number;
|
|
30
|
+
outputDir?: string;
|
|
31
|
+
}): Promise<CoverFetchResult>;
|