@yltrcc/vditor 0.3.1 → 0.3.2

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.
@@ -56,6 +56,10 @@ export const processPasteCode = (html: string, text: string, type = "sv") => {
56
56
  };
57
57
 
58
58
  export const processCodeRender = (previewPanel: HTMLElement, vditor: IVditor) => {
59
+ console.log("===== Lute 返回的 HTML (预览前) =====");
60
+ console.log(previewPanel.outerHTML);
61
+ console.log("===== 结束 =====\n");
62
+
59
63
  if (!previewPanel) {
60
64
  return;
61
65
  }
@@ -102,5 +106,167 @@ export const processCodeRender = (previewPanel: HTMLElement, vditor: IVditor) =>
102
106
  }
103
107
  }
104
108
 
109
+ // 掘金风格代码块增强
110
+ enhanceCodeBlock(previewPanel, language);
111
+
105
112
  previewPanel.setAttribute("data-render", "1");
106
113
  };
114
+
115
+ const enhanceCodeBlock = (previewPanel: HTMLElement, language: string) => {
116
+ // 检查是否已经增强过
117
+ if (previewPanel.getAttribute("data-enhanced") === "1") {
118
+ return;
119
+ }
120
+
121
+ const preElement = previewPanel.querySelector("pre");
122
+ if (!preElement) {
123
+ return;
124
+ }
125
+
126
+ const codeElement = preElement.querySelector("code");
127
+ if (!codeElement) {
128
+ return;
129
+ }
130
+
131
+ // 保存原始代码用于复制
132
+ const rawCode = codeElement.textContent || "";
133
+
134
+ // 添加行号
135
+ const codeLines = rawCode.split("\n");
136
+ const hasLineNumbers = codeElement.querySelector(".line-numbers");
137
+ if (!hasLineNumbers && codeLines.length > 0) {
138
+ const lineNumbersHTML = codeLines.map((_, index) =>
139
+ `<span class="line-number">${index + 1}</span>`
140
+ ).join("");
141
+
142
+ codeElement.innerHTML = `
143
+ <div style="display: table;">
144
+ <div class="line-numbers" style="display: table-cell; padding: 0 12px; text-align: right; border-right: 1px solid #3c3c3c; color: #6a6a6a; font-family: mononoki, Consolas, "Liberation Mono", Menlo, Courier, monospace, "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Segoe UI Symbol", "Android Emoji", "EmojiSymbols";; font-size: 14px; line-height: 1.6; user-select: none; min-width: 3em; background: #252526;">
145
+ ${codeLines.map((_, index) => `<div>${index + 1}</div>`).join("")}
146
+ </div>
147
+ <div class="code-content" style="display: table-cell; padding: 0 12px; font-family: mononoki, Consolas, "Liberation Mono", Menlo, Courier, monospace, "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", "Segoe UI Symbol", "Android Emoji", "EmojiSymbols";; font-size: 14px; line-height: 1.6; color: #d4d4d4;">
148
+ ${codeElement.innerHTML}
149
+ </div>
150
+ </div>
151
+ `;
152
+ }
153
+
154
+ // 创建标题栏
155
+ const headerElement = document.createElement("div");
156
+ headerElement.className = "vditor-code-header";
157
+ headerElement.style.cssText = `
158
+ display: flex;
159
+ align-items: center;
160
+ justify-content: space-between;
161
+ padding: 8px 12px;
162
+ background: #252526;
163
+ border-bottom: 1px solid #3c3c3c;
164
+ `;
165
+
166
+ // 左侧:折叠图标和标题
167
+ const leftElement = document.createElement("div");
168
+ leftElement.style.cssText = `
169
+ display: flex;
170
+ align-items: center;
171
+ gap: 8px;
172
+ color: #9d9d9d;
173
+ font-size: 12px;
174
+ `;
175
+
176
+ const toggleIcon = document.createElement("span");
177
+ toggleIcon.textContent = "▼";
178
+ toggleIcon.style.cssText = `
179
+ cursor: pointer;
180
+ transition: transform 0.2s;
181
+ color: #9d9d9d;
182
+ `;
183
+ toggleIcon.title = "折叠/展开";
184
+
185
+ const titleElement = document.createElement("span");
186
+ titleElement.textContent = "代码标题";
187
+ titleElement.style.cssText = `
188
+ color: #9d9d9d;
189
+ font-size: 12px;
190
+ `;
191
+
192
+ leftElement.appendChild(toggleIcon);
193
+ leftElement.appendChild(titleElement);
194
+
195
+ // 右侧:语言标签和复制按钮
196
+ const rightElement = document.createElement("div");
197
+ rightElement.style.cssText = `
198
+ display: flex;
199
+ align-items: center;
200
+ gap: 12px;
201
+ `;
202
+
203
+ const langElement = document.createElement("span");
204
+ langElement.textContent = language || "text";
205
+ langElement.style.cssText = `
206
+ color: #4ec9b0;
207
+ font-weight: 500;
208
+ font-size: 12px;
209
+ `;
210
+
211
+ const copyButton = document.createElement("span");
212
+ copyButton.textContent = "复制";
213
+ copyButton.style.cssText = `
214
+ display: flex;
215
+ align-items: center;
216
+ gap: 4px;
217
+ color: #9d9d9d;
218
+ font-size: 12px;
219
+ cursor: pointer;
220
+ padding: 4px 8px;
221
+ border-radius: 4px;
222
+ transition: all 0.2s;
223
+ `;
224
+ copyButton.title = "复制代码";
225
+
226
+ copyButton.addEventListener("mouseenter", () => {
227
+ copyButton.style.color = "#fff";
228
+ copyButton.style.background = "#3c3c3c";
229
+ });
230
+
231
+ copyButton.addEventListener("mouseleave", () => {
232
+ copyButton.style.color = "#9d9d9d";
233
+ copyButton.style.background = "transparent";
234
+ });
235
+
236
+ copyButton.addEventListener("click", () => {
237
+ navigator.clipboard.writeText(rawCode).then(() => {
238
+ const originalText = copyButton.textContent;
239
+ copyButton.textContent = "已复制!";
240
+ copyButton.style.color = "#4ec9b0";
241
+ setTimeout(() => {
242
+ copyButton.textContent = originalText;
243
+ copyButton.style.color = "#9d9d9d";
244
+ }, 2000);
245
+ }).catch(err => {
246
+ console.error("复制失败:", err);
247
+ });
248
+ });
249
+
250
+ // 折叠功能
251
+ let isCollapsed = false;
252
+ toggleIcon.addEventListener("click", () => {
253
+ isCollapsed = !isCollapsed;
254
+ const contentElement = preElement.querySelector("code");
255
+ if (contentElement) {
256
+ contentElement.style.display = isCollapsed ? "none" : "block";
257
+ }
258
+ toggleIcon.textContent = isCollapsed ? "▶" : "▼";
259
+ });
260
+
261
+ rightElement.appendChild(langElement);
262
+ rightElement.appendChild(copyButton);
263
+
264
+ headerElement.appendChild(leftElement);
265
+ headerElement.appendChild(rightElement);
266
+
267
+ // 插入标题栏
268
+ previewPanel.insertBefore(headerElement, previewPanel.firstChild);
269
+
270
+ // 标记已增强
271
+ previewPanel.setAttribute("data-enhanced", "1");
272
+ };