Compare commits
9
Commits
main
...
2ee4bb9f26
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ee4bb9f26 | ||
|
|
4bc747201f | ||
|
|
a5f1efa7cc | ||
|
|
82d384bd1f | ||
|
|
33fc8b06d6 | ||
|
|
5127df5e96 | ||
|
|
ecc1a0d77e | ||
|
|
5ef970337d | ||
|
|
197642b410 |
@@ -146,6 +146,17 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|||||||
assertCaptureableTab(tab);
|
assertCaptureableTab(tab);
|
||||||
const data = await captureCurrentTab(tab, settings);
|
const data = await captureCurrentTab(tab, settings);
|
||||||
lastCaptureData = data;
|
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 };
|
return { ok: true, actualViewportWidth: data.source?.actualViewportWidth };
|
||||||
})()
|
})()
|
||||||
.then(sendResponse)
|
.then(sendResponse)
|
||||||
|
|||||||
+15
-1
@@ -944,7 +944,7 @@
|
|||||||
const children = [];
|
const children = [];
|
||||||
const imageCandidates = getElementImageCandidates(element);
|
const imageCandidates = getElementImageCandidates(element);
|
||||||
const currentSrc = imageCandidates[0] || null;
|
const currentSrc = imageCandidates[0] || null;
|
||||||
const backgroundUrls = extractStyleImageUrls(styles);
|
let backgroundUrls = extractStyleImageUrls(styles);
|
||||||
|
|
||||||
if (/^(IMG|VIDEO|SOURCE|PICTURE)$/i.test(element.tagName)) {
|
if (/^(IMG|VIDEO|SOURCE|PICTURE)$/i.test(element.tagName)) {
|
||||||
for (const url of imageCandidates) {
|
for (const url of imageCandidates) {
|
||||||
@@ -984,6 +984,20 @@
|
|||||||
const afterNode = pseudoElementToCaptureNode(element, "::after", clientRect, assetUrls, ownClip, childContext);
|
const afterNode = pseudoElementToCaptureNode(element, "::after", clientRect, assetUrls, ownClip, childContext);
|
||||||
pushCaptureChild(children, afterNode);
|
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";
|
const type = element.tagName === "IMG" || backgroundUrls.length ? "RECTANGLE" : "FRAME";
|
||||||
return {
|
return {
|
||||||
id: `node-${++nodeCounter}`,
|
id: `node-${++nodeCounter}`,
|
||||||
|
|||||||
Reference in New Issue
Block a user