browser-plugin-creator
Version:
A modern scaffolding tool for creating browser extensions with ease
208 lines (180 loc) • 5.59 kB
JavaScript
// 内容脚本 - 页面数据收集
console.log('{{name}} 侧边栏内容脚本已加载');
// 页面分析工具
class PageAnalyzer {
constructor() {
this.init();
}
init() {
this.setupMessageListener();
// 页面加载完成后初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => this.onPageReady());
} else {
this.onPageReady();
}
}
setupMessageListener() {
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
switch (request.type) {
case 'GET_PAGE_OVERVIEW':
sendResponse(this.getPageOverview());
break;
case 'GET_DOM_TREE':
sendResponse(this.getDOMTree());
break;
case 'GET_PERFORMANCE_METRICS':
sendResponse(this.getPerformanceMetrics());
break;
case 'GET_NETWORK_DATA':
sendResponse(this.getNetworkData());
break;
case 'GET_STORAGE_DATA':
sendResponse(this.getStorageData(request.storageType));
break;
case 'ANALYZE_PAGE':
sendResponse(this.analyzePage());
break;
}
return true;
});
}
onPageReady() {
// 页面准备就绪,可以开始分析
console.log('页面DOM已就绪,开始分析');
}
getPageOverview() {
const allElements = document.querySelectorAll('*');
const uniqueTags = new Set();
const colors = new Set();
let totalSize = 0;
// 收集标签类型
allElements.forEach(el => uniqueTags.add(el.tagName.toLowerCase()));
// 收集颜色
allElements.forEach(el => {
const style = window.getComputedStyle(el);
colors.add(style.color);
colors.add(style.backgroundColor);
});
// 估算页面大小
totalSize = document.documentElement.outerHTML.length;
return {
totalElements: allElements.length,
uniqueTags: uniqueTags.size,
colorCount: colors.size,
pageSize: totalSize
};
}
getDOMTree() {
return this.buildDOMTree(document.body);
}
buildDOMTree(element, maxDepth = 3) {
if (!element || maxDepth <= 0) return null;
const tree = {
tag: element.tagName.toLowerCase(),
id: element.id || '',
className: element.className || '',
children: []
};
// 只获取直接子元素,避免性能问题
const children = Array.from(element.children).slice(0, 10);
children.forEach(child => {
const childTree = this.buildDOMTree(child, maxDepth - 1);
if (childTree) {
tree.children.push(childTree);
}
});
return tree;
}
getPerformanceMetrics() {
const navigation = performance.getEntriesByType('navigation')[0];
const paintEntries = performance.getEntriesByType('paint');
const fcp = paintEntries.find(entry => entry.name === 'first-contentful-paint');
const lcp = performance.getEntriesByType('largest-contentful-paint')[0];
return {
loadTime: Math.round(navigation.loadEventEnd - navigation.fetchStart),
domReadyTime: Math.round(navigation.domContentLoadedEventEnd - navigation.fetchStart),
fcpTime: fcp ? Math.round(fcp.startTime) : 0,
lcpTime: lcp ? Math.round(lcp.startTime) : 0
};
}
getNetworkData() {
const resources = performance.getEntriesByType('resource');
const navigation = performance.getEntriesByType('navigation')[0];
const totalRequests = resources.length + 1; // +1 for main document
const totalSize = resources.reduce((sum, resource) => sum + (resource.transferSize || 0), 0);
const totalTime = Math.round(navigation.responseEnd - navigation.fetchStart);
const resourceDetails = resources.slice(0, 20).map(resource => ({
name: resource.name.split('/').pop(),
type: resource.initiatorType,
size: resource.transferSize || 0,
time: Math.round(resource.duration)
}));
return {
totalRequests,
totalSize,
totalTime,
resources: resourceDetails
};
}
getStorageData(type) {
switch (type) {
case 'local':
return this.getLocalStorageData();
case 'session':
return this.getSessionStorageData();
case 'cookies':
return this.getCookiesData();
default:
return {};
}
}
getLocalStorageData() {
const data = {};
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
try {
data[key] = JSON.parse(localStorage.getItem(key));
} catch {
data[key] = localStorage.getItem(key);
}
}
return data;
}
getSessionStorageData() {
const data = {};
for (let i = 0; i < sessionStorage.length; i++) {
const key = sessionStorage.key(i);
try {
data[key] = JSON.parse(sessionStorage.getItem(key));
} catch {
data[key] = sessionStorage.getItem(key);
}
}
return data;
}
getCookiesData() {
const cookies = {};
document.cookie.split(';').forEach(cookie => {
const [name, value] = cookie.trim().split('=');
if (name && value) {
cookies[name] = decodeURIComponent(value);
}
});
return cookies;
}
analyzePage() {
return {
overview: this.getPageOverview(),
performance: this.getPerformanceMetrics(),
network: this.getNetworkData(),
storage: {
local: this.getLocalStorageData(),
session: this.getSessionStorageData(),
cookies: this.getCookiesData()
}
};
}
}
// 初始化页面分析器
new PageAnalyzer();