refactor: popup 流程简化 — 采集→获取→转化→background下载
This commit is contained in:
+20
-36
@@ -1,4 +1,4 @@
|
|||||||
const SETTINGS_KEY = 'webToPPTSettings';
|
const SETTINGS_KEY = 'webToPixsoSettings';
|
||||||
const DEFAULT_SETTINGS = { useProxy: false, concurrency: '8', captureMode: 'mixed', captureWidth: null };
|
const DEFAULT_SETTINGS = { useProxy: false, concurrency: '8', captureMode: 'mixed', captureWidth: null };
|
||||||
const MIN_CAPTURE_WIDTH = 320;
|
const MIN_CAPTURE_WIDTH = 320;
|
||||||
const MAX_CAPTURE_WIDTH = 3840;
|
const MAX_CAPTURE_WIDTH = 3840;
|
||||||
@@ -16,19 +16,6 @@ function normalizeCaptureWidth(value, fallback = null) {
|
|||||||
return Math.max(MIN_CAPTURE_WIDTH, Math.min(MAX_CAPTURE_WIDTH, number));
|
return Math.max(MIN_CAPTURE_WIDTH, Math.min(MAX_CAPTURE_WIDTH, number));
|
||||||
}
|
}
|
||||||
|
|
||||||
function normalizeSettings(value = {}) {
|
|
||||||
return {
|
|
||||||
useProxy: Boolean(value.useProxy),
|
|
||||||
captureMode: 'mixed',
|
|
||||||
captureWidth: normalizeCaptureWidth(value.captureWidth, null)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getSettings() {
|
|
||||||
const result = await chrome.storage.local.get({ [SETTINGS_KEY]: DEFAULT_SETTINGS });
|
|
||||||
return normalizeSettings(result[SETTINGS_KEY]);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getCurrentViewportWidth() {
|
async function getCurrentViewportWidth() {
|
||||||
try {
|
try {
|
||||||
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
|
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
|
||||||
@@ -65,45 +52,42 @@ async function exportPptx() {
|
|||||||
setProgress(5, '准备采集...');
|
setProgress(5, '准备采集...');
|
||||||
|
|
||||||
const captureWidth = normalizeCaptureWidth(captureWidthInput.value, null);
|
const captureWidth = normalizeCaptureWidth(captureWidthInput.value, null);
|
||||||
const settings = { ...DEFAULT_SETTINGS, captureWidth };
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 1. 抓取 DOM
|
// 1. 触发采集(background 会缓存数据)
|
||||||
setProgress(15, '正在采集页面...');
|
setProgress(15, '正在采集页面...');
|
||||||
const response = await chrome.runtime.sendMessage({
|
const captureResult = await chrome.runtime.sendMessage({
|
||||||
type: 'WEB_TO_PPT_CAPTURE_START',
|
type: 'WEB_TO_PPT_CAPTURE_START',
|
||||||
options: settings
|
options: { captureWidth }
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response || !response.ok) {
|
if (!captureResult || !captureResult.ok) {
|
||||||
throw new Error(response?.error || '采集失败');
|
throw new Error(captureResult?.error || '采集失败');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 获取 JSON 数据(从 background 返回的文件路径读取不了,直接从 background 拿数据)
|
// 2. 获取缓存数据
|
||||||
// 需要让 background 返回 JSON 数据而不是文件
|
setProgress(40, '采集完成,获取数据...');
|
||||||
setProgress(40, '采集完成,正在转化...');
|
const dataResult = await chrome.runtime.sendMessage({
|
||||||
|
|
||||||
// background 已经下载了 JSON 文件,但我们需要数据来转化
|
|
||||||
// 用另一个消息获取数据
|
|
||||||
const dataResponse = await chrome.runtime.sendMessage({
|
|
||||||
type: 'WEB_TO_PPT_GET_DATA'
|
type: 'WEB_TO_PPT_GET_DATA'
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!dataResponse || !dataResponse.ok) {
|
if (!dataResult || !dataResult.ok) {
|
||||||
throw new Error(dataResponse?.error || '获取数据失败');
|
throw new Error(dataResult?.error || '获取数据失败');
|
||||||
}
|
}
|
||||||
|
|
||||||
const jsonData = dataResponse.data;
|
const jsonData = dataResult.data;
|
||||||
|
|
||||||
// 3. 转化
|
// 3. 转化
|
||||||
setProgress(50, '正在生成 PPTX...');
|
setProgress(50, '正在生成 PPTX...');
|
||||||
const schema = await WebToPPT.convertToPptx(jsonData, (msg) => {
|
const schema = await WebToPPT.convertToPptx(jsonData, (msg) => {
|
||||||
setProgress(50 + Math.min(40, Math.floor(Math.random() * 40)), msg);
|
setProgress(60, msg);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 4. 生成 PPTX 并通过 background 下载
|
// 4. 生成 PPTX blob
|
||||||
setProgress(90, '正在打包...');
|
setProgress(85, '正在打包...');
|
||||||
const blob = await WebToPPT.schemaToPptxBlob(schema);
|
const blob = await WebToPPT.schemaToPptxBlob(schema);
|
||||||
|
|
||||||
|
// 5. 转 base64
|
||||||
const buffer = await blob.arrayBuffer();
|
const buffer = await blob.arrayBuffer();
|
||||||
const bytes = new Uint8Array(buffer);
|
const bytes = new Uint8Array(buffer);
|
||||||
let binary = '';
|
let binary = '';
|
||||||
@@ -112,7 +96,7 @@ async function exportPptx() {
|
|||||||
}
|
}
|
||||||
const base64 = btoa(binary);
|
const base64 = btoa(binary);
|
||||||
|
|
||||||
// 5. 让 background 执行下载
|
// 6. 让 background 下载
|
||||||
setProgress(95, '正在下载...');
|
setProgress(95, '正在下载...');
|
||||||
const title = jsonData.source?.title || 'webpage';
|
const title = jsonData.source?.title || 'webpage';
|
||||||
const safeTitle = title.replace(/[\\/:*?"<>|]+/g, '-').replace(/\s+/g, '-').slice(0, 64) || 'webpage';
|
const safeTitle = title.replace(/[\\/:*?"<>|]+/g, '-').replace(/\s+/g, '-').slice(0, 64) || 'webpage';
|
||||||
@@ -123,13 +107,13 @@ async function exportPptx() {
|
|||||||
base64,
|
base64,
|
||||||
filename
|
filename
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!dlResult || !dlResult.ok) {
|
if (!dlResult || !dlResult.ok) {
|
||||||
throw new Error(dlResult?.error || '下载失败');
|
throw new Error(dlResult?.error || '下载失败');
|
||||||
}
|
}
|
||||||
|
|
||||||
setProgress(100, `已导出:${filename}`);
|
setProgress(100, '导出完成');
|
||||||
setResult('success', '导出完成');
|
setResult('success', '导出完成');
|
||||||
// 不自动关闭 popup,等用户选完保存位置
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setProgress(0, error.message || String(error));
|
setProgress(0, error.message || String(error));
|
||||||
|
|||||||
Reference in New Issue
Block a user