9 Commits
Author SHA1 Message Date
李进 2ee4bb9f26 Reapply "Reapply "fix: backgroundUrls 从 const 改为 let,允许 SVG 赋值""
This reverts commit 4bc747201f.
2026-07-27 15:49:57 +08:00
李进 4bc747201f Revert "Reapply "fix: backgroundUrls 从 const 改为 let,允许 SVG 赋值""
This reverts commit a5f1efa7cc.
2026-07-27 15:49:56 +08:00
李进 a5f1efa7cc Reapply "fix: backgroundUrls 从 const 改为 let,允许 SVG 赋值"
This reverts commit 82d384bd1f.
2026-07-27 15:49:56 +08:00
李进 82d384bd1f Revert "fix: backgroundUrls 从 const 改为 let,允许 SVG 赋值"
This reverts commit 33fc8b06d6.
2026-07-27 15:49:42 +08:00
李进 33fc8b06d6 fix: backgroundUrls 从 const 改为 let,允许 SVG 赋值 2026-07-27 15:48:20 +08:00
李进 5127df5e96 debug: SVG 处理日志 2026-07-27 15:45:51 +08:00
李进 ecc1a0d77e fix: SVG tag 大小写判断修复 2026-07-27 15:40:47 +08:00
李进 5ef970337d feat: SVG 图标序列化为图片
SVG 元素(如 Octicons)在 capture 阶段序列化为 SVG data URL,
存储到 backgroundImages,转化时作为图片渲染到 PPT。
2026-07-27 15:34:35 +08:00
李进 197642b410 debug: 采集后保存 JSON 供调试 2026-07-27 15:28:47 +08:00
2 changed files with 26 additions and 1 deletions
+11
View File
@@ -146,6 +146,17 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
assertCaptureableTab(tab);
const data = await captureCurrentTab(tab, settings);
lastCaptureData = data;
// 调试:保存 JSON 到 Downloads
try {
const json = JSON.stringify(data, null, 2);
const encoded = btoa(unescape(encodeURIComponent(json)));
const title = data.source?.title || 'debug';
const safe = title.replace(/[\\/:*?"<>|]+/g, '-').slice(0, 32);
await chrome.downloads.download({
url: 'data:application/json;base64,' + encoded,
filename: 'web-to-ppt/' + safe + '-' + Date.now() + '.json'
});
} catch(e) {}
return { ok: true, actualViewportWidth: data.source?.actualViewportWidth };
})()
.then(sendResponse)
+15 -1
View File
@@ -944,7 +944,7 @@
const children = [];
const imageCandidates = getElementImageCandidates(element);
const currentSrc = imageCandidates[0] || null;
const backgroundUrls = extractStyleImageUrls(styles);
let backgroundUrls = extractStyleImageUrls(styles);
if (/^(IMG|VIDEO|SOURCE|PICTURE)$/i.test(element.tagName)) {
for (const url of imageCandidates) {
@@ -984,6 +984,20 @@
const afterNode = pseudoElementToCaptureNode(element, "::after", clientRect, assetUrls, ownClip, childContext);
pushCaptureChild(children, afterNode);
// SVG → 序列化为 data URL 图片
if ((element.tagName === "SVG" || element.tagName === "svg") && !backgroundUrls.length) {
try {
const svgClone = element.cloneNode(true);
if (!svgClone.getAttribute('xmlns')) svgClone.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
const svgStr = new XMLSerializer().serializeToString(svgClone);
const svgDataUrl = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(svgStr)));
backgroundUrls = [svgDataUrl];
console.log('[WebToPPT] SVG captured:', (element.className || element.id || '').slice(0, 30), 'size:', svgStr.length);
} catch (e) {
console.warn('[WebToPPT] SVG capture failed:', e.message, element.tagName, (element.className || '').slice(0, 30));
}
}
const type = element.tagName === "IMG" || backgroundUrls.length ? "RECTANGLE" : "FRAME";
return {
id: `node-${++nodeCounter}`,