-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontentScript.js
More file actions
231 lines (206 loc) · 8.07 KB
/
contentScript.js
File metadata and controls
231 lines (206 loc) · 8.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
// 如果侧边栏不存在,则创建;如果存在则删除(初始状态下采用创建方式)
if (!document.getElementById('my-extension-sidebar')) {
createSidebarElement();
}
// 确保消息监听器正确处理getContent请求
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === 'getContent') {
console.log('收到获取内容请求');
const content = document.body.innerText || document.body.textContent || '';
console.log(`返回内容长度: ${content.length}`);
sendResponse({ content: content });
} else if (message.action === 'closeSidebar') {
const sidebar = document.getElementById('my-extension-sidebar');
if (sidebar) {
sidebar.remove();
updateSidebarState(false);
}
sendResponse({ success: true });
} else if (message.action === 'toggleSidebar') {
const sidebar = document.getElementById('my-extension-sidebar');
if (sidebar) {
sidebar.remove();
updateSidebarState(false);
} else {
createSidebarElement();
updateSidebarState(true);
}
sendResponse({ success: true });
}
return true; // 保持连接打开,以便异步响应
});
// 监听来自sidebar的消息
window.addEventListener('message', function(event) {
// 确保消息来源是我们的iframe
const sidebar = document.getElementById('my-extension-sidebar');
const iframe = sidebar ? sidebar.querySelector('iframe') : null;
if (iframe && event.source === iframe.contentWindow) {
if (event.data.action === 'getContent') {
event.source.postMessage({
response: 'content',
content: document.body.innerText
}, '*');
} else if (event.data.action === 'closeSidebar') {
sidebar.remove();
updateSidebarState(false);
} else if (event.data.action === 'startAggregateSummary') {
// 转发聚合摘要请求到background.js
chrome.runtime.sendMessage({ action: 'startAggregateSummary' }, function(response) {
event.source.postMessage({
response: 'aggregateSummary',
success: response?.success || false
}, '*');
});
} else if (event.data.action === 'resizeSidebar') {
// 处理侧边栏大小调整
if (sidebar) {
sidebar.style.width = event.data.width;
console.log('调整侧边栏宽度为:', event.data.width);
}
}
}
});
function createSidebarElement() {
const sidebar = document.createElement('div');
sidebar.id = 'my-extension-sidebar';
sidebar.style.position = 'fixed';
sidebar.style.top = '0';
sidebar.style.right = '0';
// 从localStorage读取宽度,如果没有则使用默认值30%
const savedWidth = localStorage.getItem('shidu_sidebar_width') || '30%';
sidebar.style.width = savedWidth;
sidebar.style.height = '100%';
sidebar.style.backgroundColor = '#fff';
sidebar.style.borderLeft = '1px solid #ccc';
sidebar.style.zIndex = '9999';
sidebar.style.boxShadow = '0 0 10px rgba(0,0,0,0.2)';
sidebar.style.overflow = 'auto';
sidebar.style.transition = 'width 0.1s ease'; // 添加平滑过渡效果
document.body.appendChild(sidebar);
if (window.location.href.startsWith('chrome://')) {
sidebar.innerHTML = `<div style="padding: 20px;">
<h2>无法在Chrome内部页面使用</h2>
<p>由于浏览器安全限制,此扩展无法在Chrome内部页面上运行。</p>
<button id="close-sidebar">关闭</button>
</div>`;
const closeBtn = document.getElementById('close-sidebar');
if (closeBtn) {
closeBtn.addEventListener('click', () => {
sidebar.remove();
updateSidebarState(false);
});
}
} else {
// 使用iframe加载sidebar.html,这样可以保持Chrome API的上下文
const iframe = document.createElement('iframe');
iframe.style.width = '100%';
iframe.style.height = '99%';
iframe.style.border = 'none';
iframe.src = chrome.runtime.getURL('sidebar.html');
sidebar.appendChild(iframe);
// 设置一个全局对象来与iframe通信
window.sidebarInterface = {
getContent: () => document.body.innerText,
closeSidebar: () => {
sidebar.remove();
updateSidebarState(false);
}
};
}
}
function handleSummarize() {
const content = document.body.innerText;
const summaryElement = document.getElementById('summary');
if (!summaryElement) return;
summaryElement.innerHTML = '<p>正在生成摘要,请稍候...</p>';
generateSummaryWithLocalModel(content)
.then(summary => {
summaryElement.innerHTML = `
<h3>网页内容摘要:</h3>
<div style="white-space: pre-wrap; font-size: 14px; border: 1px solid #ddd; padding: 10px; background-color: #f9f9f9;">
${summary.replace(/</g, '<').replace(/>/g, '>')}
</div>
`;
})
.catch(error => {
summaryElement.innerHTML = `
<h3>摘要生成失败:</h3>
<p style="color: red;">${error.message}</p>
<button id="showRawContent">显示原始内容</button>
`;
const showRawBtn = document.getElementById('showRawContent');
if (showRawBtn) {
showRawBtn.addEventListener('click', () => showOriginalContent(content, summaryElement));
}
});
}
function showOriginalContent(content, element) {
const maxLength = 5000;
const displayContent = content.length > maxLength ?
content.substring(0, maxLength) + '...(内容过长,已截断)' :
content;
element.innerHTML = `
<h3>捕获到的网页内容:</h3>
<div style="max-height: 400px; overflow: auto; white-space: pre-wrap; font-size: 12px; border: 1px solid #ddd; padding: 10px; background-color: #f9f9f9;">
${displayContent.replace(/</g, '<').replace(/>/g, '>')}
</div>
<p style="margin-top: 10px; font-size: 12px; color: #666;">
总字符数: ${content.length}
</p>
`;
}
// 使用本地模型生成摘要的函数
async function generateSummaryWithLocalModel(text) {
// 本地模型的URL,可以在选项页面中配置
const localModelUrl = 'http://localhost:8000/v1/chat/completions'; // 默认地址,可根据实际情况修改
// 准备请求数据
const messages = [
{
"role": "system",
"content": "你是一个专业的文本摘要助手。请为以下文本生成一个简洁、全面的摘要,突出关键信息和主要观点。"
},
{
"role": "user",
"content": text
}
];
const requestData = {
"model": "local-model", // 本地模型名称,可根据实际情况修改
"messages": messages,
"temperature": 0.7,
"max_tokens": -1,
"stream": false
};
try {
// 发送请求到本地模型
const response = await fetch(localModelUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(requestData),
timeout: 60000 // 60秒超时
});
// 检查响应状态
if (!response.ok) {
throw new Error(`本地模型返回错误状态码: ${response.status}`);
}
// 解析响应
const result = await response.json();
// 提取回复内容
if (result.choices && result.choices.length > 0 &&
result.choices[0].message && result.choices[0].message.content) {
return result.choices[0].message.content.trim();
} else {
throw new Error('无法从模型响应中提取摘要内容');
}
} catch (error) {
console.error('调用本地模型出错:', error);
throw new Error(`生成摘要失败: ${error.message}`);
}
}
function updateSidebarState(isVisible) {
chrome.runtime.sendMessage({
action: 'updateSidebarState',
isVisible: isVisible
}); }