重构:提交全新项目代码
This commit is contained in:
47
packages/bookmark-sync/src/custom-bookmark-bar/newtab.html
Normal file
47
packages/bookmark-sync/src/custom-bookmark-bar/newtab.html
Normal file
@@ -0,0 +1,47 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>我的自定义书签</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
#bookmark-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 15px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.bookmark-item {
|
||||
display: block;
|
||||
width: 120px;
|
||||
padding: 15px;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
text-align: center;
|
||||
}
|
||||
.bookmark-item:hover {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>我的书签管理器</h2>
|
||||
<!-- 文件夹切换下拉框 -->
|
||||
<select id="folder-selector">
|
||||
<option value="1">书签栏 (ID: 1)</option>
|
||||
<!-- 其他文件夹可以通过代码动态加载到这里 -->
|
||||
</select>
|
||||
|
||||
<!-- 书签渲染容器 -->
|
||||
<div id="bookmark-container"></div>
|
||||
|
||||
<script src="popup.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
76
packages/bookmark-sync/src/custom-bookmark-bar/popup.ts
Normal file
76
packages/bookmark-sync/src/custom-bookmark-bar/popup.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
// 递归提取某个节点下的所有书签 URL(防止文件夹嵌套)
|
||||
function extractUrls(
|
||||
bookmarkNode: chrome.bookmarks.BookmarkTreeNode[],
|
||||
): string[] {
|
||||
let urls: string[] = [];
|
||||
for (const node of bookmarkNode) {
|
||||
if (node.url) {
|
||||
urls.push(node.url);
|
||||
} else if (node.children) {
|
||||
urls = urls.concat(extractUrls(node.children));
|
||||
}
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
|
||||
// 渲染指定 ID 文件夹下的书签
|
||||
async function renderBookmarksByFolderId(folderId: string) {
|
||||
try {
|
||||
const results = await chrome.bookmarks.getSubTree(folderId);
|
||||
const folderNode = results[0];
|
||||
|
||||
if (!folderNode || !folderNode.children) return;
|
||||
|
||||
const container = document.getElementById("bookmark-container");
|
||||
if (container) container.innerHTML = "";
|
||||
|
||||
// 遍历直接子节点
|
||||
folderNode.children.forEach((bookmark) => {
|
||||
if (bookmark.url) {
|
||||
const link = document.createElement("a");
|
||||
link.className = "bookmark-item";
|
||||
link.href = bookmark.url;
|
||||
link.textContent = bookmark.title || bookmark.url;
|
||||
// 自动获取网站 favicon 图标
|
||||
const faviconUrl = `https://www.google.com/s2/favicons?domain=${new URL(bookmark.url).hostname}&sz=32`;
|
||||
link.innerHTML = `<img src="${faviconUrl}" style="vertical-align: middle; margin-right: 5px;">${bookmark.title}`;
|
||||
container?.appendChild(link);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("获取书签失败:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化:自动获取所有一级文件夹并填充到下拉框
|
||||
async function initFolderSelector() {
|
||||
const results = await chrome.bookmarks.getTree();
|
||||
const bookmarkBar = results[0].children?.[0]; // ID为1的书签栏
|
||||
const selector = document.getElementById(
|
||||
"folder-selector",
|
||||
) as HTMLSelectElement;
|
||||
|
||||
if (bookmarkBar && bookmarkBar.children) {
|
||||
bookmarkBar.children.forEach((folder) => {
|
||||
// 只把文件夹加到下拉框里
|
||||
if (!folder.url && folder.id !== "1") {
|
||||
const option = document.createElement("option");
|
||||
option.value = folder.id || "";
|
||||
option.textContent = folder.title || "未命名文件夹";
|
||||
selector.appendChild(option);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 绑定切换事件
|
||||
selector.addEventListener("change", (e) => {
|
||||
const targetId = (e.target as HTMLSelectElement).value;
|
||||
renderBookmarksByFolderId(targetId);
|
||||
});
|
||||
|
||||
// 默认渲染书签栏
|
||||
renderBookmarksByFolderId("1");
|
||||
}
|
||||
|
||||
// 页面加载完成后启动
|
||||
document.addEventListener("DOMContentLoaded", initFolderSelector);
|
||||
Reference in New Issue
Block a user